Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - class_OpenGL

#101
Programación C/C++ / Re: Archivos en C
26 Agosto 2016, 09:30 AM
Lo primero si que lo tuve en cuenta en el código. Lo segundo, pues no :P
#102
Programación C/C++ / Re: Archivos en C
26 Agosto 2016, 04:59 AM
Cita de: NoBass en 26 Agosto 2016, 02:52 AM1.-Si leo un archivo en binario (por ejemplo un pdf) y lo copio a otro archivo, que guardo como pdf, el documento resulta ilegible. Entiendo que ésto es porque el archivo original tiene un formato determinado, que al copiar bit a bit no se mantiene o que hay que interpretar de algún modo. Imagino la copia (bueno de hecho así la veo cuando la abro con el editor de texto) como una montaña absurda de caracteres descabellados que hay que organizar de algún modo, pero intuyo que es algo bastante complejo.

Eso es rotundamente falso. Si abres un archivo en binario, copias byte a byte y lo guardas en otro archivo con la misma extensión, debería ser una copia exacta, y como tal, no debería haber problemas con la copia. Te dejo un código que copia exactamente un archivo a otro:

#include <string.h>
#include <stdio.h>

#define MAX_PATH 4096

int main() {
// Puedes poner MAX_PATH como quieras, o saber este valor a través de librerías
// no estándares
char ruta_entrada[MAX_PATH];
char ruta_salida[MAX_PATH];
FILE *entrada;
FILE *salida;
char byte;
int salir = 0;

// Obtenemos rutas
fprintf(stdout, "Introduzca la ruta del archivo a copiar: ");
fgets(ruta_entrada, MAX_PATH, stdin);
ruta_entrada[strlen(ruta_entrada) - 1] = '\0';
fprintf(stdout, "Introduzca la ruta del archivo de destino: ");
fgets(ruta_salida, MAX_PATH, stdin);
ruta_salida[strlen(ruta_salida) - 1] = '\0';

// Abrimos archivos
entrada = fopen(ruta_entrada, "rb");
if(NULL == entrada) {
fprintf(stderr, "Error abriendo archivo de entrada en '%s'\n", ruta_entrada);
perror("Detalles");
return -1;
}

salida = fopen(ruta_salida, "wb");
if(NULL == salida) {
fprintf(stderr, "Error abriendo archivo de salida en '%s'\n", ruta_salida);
perror("Detalles");
return -1;
}

// Copiando datos
while(0 == salir) {
byte = fgetc(entrada);

if(0 == feof(entrada)) {
fputc(byte, salida);

if(0 != ferror(entrada) || 0 != ferror(salida)) {
fprintf(stderr, "Error leyendo|escribiendo byte\n");
perror("Detalles");
return -1;
}
} else {
salir = 1;
}
}

// Terminando...
fprintf(stdout, "La copia de archivos ha finalizado\n");

fclose(entrada);
fclose(salida);
return 0;
}


Evidentemente, esto no es lo más básico, sino que es una forma "muy segura" de copiar archivos (se podrían haber omitido la comprobación de que los archivos existen, los mensajes de error...)

Espero que te sea de ayuda.

PD.: Probé el código con un PDF, y funcionó perfectamente :D
#104
Hola, muy buenas. Estaba viendo cómo se hacía una unidad de arranque desde ensamblador (NASM), pero tengo problemas con el registro DS. Muestro este código para mostrar mi duda:

Código (asm) [Seleccionar]
BITS 16

start:
xor ax, ax                 ; Set data segment to where we're loaded
mov ds, ax

mov ax, text_string
add ax, 7C00h
mov si, ax                 ; Put string position into SI
call print_string          ; Call our string-printing routine

jmp $                      ; Jump here - infinite loop!


text_string: db 'This is my cool new OS!', 0


print_string:                      ; Routine: output string in SI to screen
mov ah, 0Eh                ; int 10h 'print char' function

.repeat:
lodsb                      ; Get character from string
cmp al, 0
je .done                   ; If char is zero, end of string
int 10h                    ; Otherwise, print it
jmp .repeat

.done:
ret


times 510-($-$$) db 0      ; Pad remainder of boot sector with 0s
dw 0xAA55


Es un código sencillito, pero funciona. El problema está en que si hago que el registro DS valga 0x07C0, el ordenador no arranca con esta unidad de arranque, pero si calculo manualmente la dirección de la cadena de texto y hago que DS valga 0, el ordenador si que arranca con esta unidad.

Código con el que funciona:
Código (asm) [Seleccionar]
BITS 16

start:
xor ax, ax                 ; Lo ponemos como 0
mov ds, ax

mov ax, text_string        ; Calculo manualmente la dirección de la caedna
add ax, 7C00h
mov si, ax                 ; La guardo en SI
       
       ...


Código con el que no funciona:
Código (asm) [Seleccionar]
BITS 16

start:
mov ax 0x07C0          ; Lo ponemos como 0
mov ds, ax

mov ax, text_string    ; El cálculo debería ser DS * 0x10 + SI, lo que es lo mismo que
                              ; 0x07C0 * 0x10 + SI, lo que es lo mismo que 0x7C00 + SI, que
                              ; a su vez es lo mismo que el cálculo manual antes expuesto
mov si, ax             ; La guardo en SI
       
       ...


O hay algo que se me escapa, o es muy extraño todo... Gracias de antemano!




Vale, me he dado cuenta de que xor limpia parte/todo el registro FLAGS

He obtenido el registro con LAHF. Antes de usar xor, LAHF retornaba, en binario, 01000110, y después de usar xor, LAHF retornaba 00000000. He intentado hacer lo siguiente, pero sigue sin funcionar:

Código (asm) [Seleccionar]
mov ah, 0x00
SAHF
CLC
CLD
CLTS
mov ax, 0x07C0
mov ds, ax


Pero con este código si que funciona (algo hace XOR de lo que no me doy cuenta...):
Código (asm) [Seleccionar]
xor ax, ax            ; Algo más tiene que hacer XOR, porque aun reemplazando el valor de ax, sin XOR no funciona
mov ax, 0x07C0        ; Aquí reemplazamos todo ax
mov ds, ax


Espero que me puedan ayudar :D
#105
Hola, muy buenas, me explico. La pregunta que tengo es dónde se guardan las variables. Yo tenía entendido que se guardan en un especie de bloque de memoria asignado para cada programa llamado 'pila', pero según estoy leyendo por ahí, las variables pueden ser guardadas entre código y código del ejecutable. En ensamblador, por ejemplo, podríamos escribir 'mylabel: db 'Message here', 0' (ejemplo de Internet). En ese espacio del ejecutable, se guarda una serie de bytes que contienen "Message here", por lo que podrías decir que esa memoria está entre código y código, no en la 'pila'

Espero que mi duda se haya entendido, no sabía muy bien como explicarla... ¡Muchas gracias de antemano!
#106
Jajaja, habrá que ver que nos podemos inventar
#107
Si eres como esas personas que codifican sin poner tabulaciones, espacios, deja los códigos super comprimidos y la gente no le gusta tu estilo, ¡¡aquí te traigo la forma de seguir con tu estilo y además de una forma bonita!!

          #include<stdio.h>




                 int
                main(
               ){float
              rad=0.0f;
             float peri;
            float   areac
           =.0f;     const
          float       pi_2=
         1.5707f;char*areas=
        "Area";fprintf(stdout
       ,"Radio: ");scanf("%f",
      &rad);              peri=
     4.00f                 *pi_2
    *rad;                   areac
   =2.0f                     *pi_2
  *rad*                       *&rad
;fprintf                     (stdout,




"Perimeter: %f\n",peri);fprintf(stdo\
ut,"%s: %f",areas, areac); return 0;}


Para aquel que se lo pregunte, como si no estuviera claro, este código te pide un radio para calcular su perímetro y área asociado

¡Espero que adoptéis este estilo tan maravilloso de programación!
#108
Yo acabo de compilar el código, y hay MUCHIIISIMOS más errores que los que mencionas... Simplemente voy a poner un ejemplo para que no se me tome por mentiroso:

C:/MinGW64/mingw64/x86_64-w64-mingw32/include/c++/ostream:574:5: note:   templat
e argument deduction/substitution failed:
clasesvehiculo/vehiculo.cpp:109:52: note:   cannot convert 'Vehiculo::mostrarPre
cio()' (type 'void') to type 'const unsigned char*'
                cout << "Precio: " << mostrarPrecio() << endl;
                                                   ^


Ese error viene de este fragmento:

Código (cpp) [Seleccionar]
void Vehiculo::mostrarPrecio()
{
       return precio;
}

[...]

void Vehiculo::mostrarVehiculo()
{
       [...]
       cout << "Precio: " << mostrarPrecio() << endl;
}


La función, en teoría, tendría que retornar algo, pero le pusiste que retornara void...

Por si quieres la lista completa de errores lanzada por MinGW, aquí la tienes:
http://www.mediafire.com/download/lcchftx34bpjhah/log.txt

Para que veas la cantidad de errores, el archivo ocupa 211 KB XDD
#109
El código ASCII como tal solo recoge los primeros 127 caracteres de la tabla, en la cual no están ni la ñ ni las vocales acentuadas. Por lo tanto, en la cabecera de tu programa tendrás que especificar que vas a usar una codificación ASCII extendida, la codificación UTF-8. Aquí tienes lo que tienes que incluir:

Código (python) [Seleccionar]
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#110
Aquí dejo un programa que hice en C para un problema de Project Euler. El programa calcula la suma total de los dígitos de factorial de 200 (en realidad, el ejercicio pedía de 100, pero puse 200 para que tuviera más de 200 dígitos). En el programa, para obtener los dígitos, tengo que sacar el módulo, así que funciona correctamente (lo digo porque Project Euler dictaminó que mi respuesta era buena).

#include <stdlib.h>
#include <stdio.h>

typedef struct {
unsigned char *bytes;
unsigned int num_bytes;
} big_int;

void set_big_int(big_int *result, unsigned char number);
void multiply(big_int *result, unsigned char number);
void divide(big_int *result, unsigned char denominator);
unsigned char get_module(big_int *result, unsigned char denominator);
void factorial(big_int *result, unsigned char number);
int is_zero(big_int *big_integer);

int main() {
big_int big_integer = {NULL, 0};
unsigned char digit;
unsigned int num_digits = 0;
unsigned int result = 0;

fprintf(stdout, "Adding all digits of 200!...\n");

factorial(&big_integer, 200);

while(is_zero(&big_integer) == 0) {
num_digits++;

digit = get_module(&big_integer, 10);
fputc(digit + '0', stdout);
result += digit;

divide(&big_integer, 10);
}

fprintf(stdout, "\n\nDigit sum result: %u\n", result);
fprintf(stdout, "Number of digits: %u", num_digits);

fgetc(stdin);
return 0;
}

void set_big_int(big_int *result, unsigned char number) {
if(result->bytes != NULL)
free(result->bytes);

result->bytes = malloc(sizeof(unsigned char));
result->bytes[0] = number;
result->num_bytes = 1;
}

void multiply(big_int *result, unsigned char number) {
register int i;
unsigned int rest = 0;

for(i = 0; i < result->num_bytes; i++) {
rest = result->bytes[i] * number + rest;
result->bytes[i] = rest & 0x000000FF;
rest >>= 8;

if(rest != 0 && i+1 == result->num_bytes) {
result->num_bytes += 1;
realloc(result->bytes, result->num_bytes);
result->bytes[i+1] = 0;
}
}
}

void divide(big_int *result, unsigned char denominator) {
register int i;
unsigned int module = 0;
unsigned int new_size = result->num_bytes;

for(i = result->num_bytes-1; i >= 0; i--) {
module = (unsigned int)result->bytes[i] + (module << 8);
result->bytes[i] = module/denominator;
module %= denominator;
}

for(i = result->num_bytes-1; i >= 0 && result->bytes[i] == 0; i--)
new_size--;

if(new_size != result->num_bytes) {
result->num_bytes = new_size;
realloc(result->bytes, new_size);
}
}

unsigned char get_module(big_int *result, unsigned char denominator) {
register int i;
unsigned int module = 0;

for(i = result->num_bytes-1; i >= 0; i--)
module = ((unsigned int)result->bytes[i] + (module << 8))%denominator;

return module;
}

void factorial(big_int *result, unsigned char number) {
unsigned char i;

set_big_int(result, 1);
for(i = 2; i <= number; i++)
multiply(result, i);
}

int is_zero(big_int *big_integer) {
register unsigned int i;
unsigned int result = 1;

for(i = 0; result == 1 && i < big_integer->num_bytes; i++)
result = big_integer->bytes[i] == 0;

return result;
}


Además, le he agregado para que imprima los dígitos en Little Endian, así que la salida del programa para calcular el factorial de 200 sería...

00000000000000000000000000000000000000000000000002747379830732698722222987169785
80071532604230714091306220668659755047521230423093757042424257723584928247221314
68192330452042466154126544229349889693732713367072758264311139928259426629160501
73624209724675203883691983121277140932648911048240302924330436994495344233524749
2362371786779531592260581239312363255305097463768756887

Digit sum result: 1404
Number of digits: 375