Ver Mensaje Individual
  #3 (permalink)  
Antiguo 16/04/2009, 13:44
druha
 
Fecha de Ingreso: marzo-2009
Mensajes: 16
Antigüedad: 15 años, 8 meses
Puntos: 0
Respuesta: Por qué esto no funciona? Misterios de C...

Hola, el código lo puse bastante simplificado para ir al grano, ya que mi código original está repartido en varias funciones de diferentes ficheros y es relativamente complejo. De todas formas, mirando el ejemplo que pusiste, he cambiado scanf por gets y efectivamente de esa forma funciona. El problema es que la información que quiero escribir en el fichero realmente no es leída del teclado, como dije es sólo un ejemplo simplificado para que se viese cual es el meollo de la cuestión.

Lo que pretendo hacer en realidad es leer información de un socket y volcar parte de ella en un fichero. La información llega en varias piezas en diferentes momentos, por lo que la escritura es gradual, según voy recibiendo la información. En la práctica, lo que me llega no son las piezas enteras, sino subpiezas. Así que con la información que tengo que escribir me viene adjunto el indice de la pieza (en otras palabras, el desplazamiento dentro del fichero), el desplazamiento dentro de la pieza y el tamaño de esa subpieza. Los mensajes que recibo tienen este formato:

<longitud total (4bytes)><identificador (1 byte)><indice de pieza (4 bytes)><desplazamiento dentro de la pieza (4 bytes)><datos (x bytes)>

Cuando me llega este mensaje, leo la longitud total y el identificador, y en función del valor de este último, con un switch, decido qué hacer. El caso involucrado es este, donde se obtiene la información del desplazamiento y demás, y se escribe al fichero llamando a "volcar_a_fichero" (buff apunta a la parte del mensaje que estoy leyendo en cada momento):

Código:
case 7:

memcpy((void *)&index,buff,sizeof(int));
index=ntohl(index);
buff=buff+4;	
memcpy((void *)&begin,buff,sizeof(int));
begin=ntohl(begin);
buff=buff+4;
descarga->descargado[index]+=(tam-9);
offset=buff;		
volcar_a_fichero(descarga->fichero_fisico,index*descarga->tam_pieza+begin,tam-9,offset);
bytes+=tam-9;
printf("Recibiendo pieza %d, bloque %d, tamaño %d\n",index,begin,tam-9);

break;
"volcar_a_fichero" hace esto:

Código:
void volcar_a_fichero(FILE *fichero,int desplazamiento,int lon,void *datos) {
	fseek(fichero,desplazamiento,SEEK_SET);
	fwrite(datos,1,lon,fichero);
}
El código que implementa el menú y que inicia el proceso de descarga de datos es el caso 1. El código que mostré antes estaría dentro de la función "descarga", que se llama dentro del if.

Código:
	while(1) {
		//Se muestran las opciones por pantalla...
		printf("Opción: ");
		scanf("%d",&opt);
		switch(opt) {
			case 1:
				descarga=preparar_descarga(buffer);
				if(descarga!=NULL) {
					descargar(descarga);
					liberar_descarga(descarga);
				}
				else printf("No se pudo realizar la descarga\n");				
				break;
                       //Otros casos....
			case 4:
				printf("Salir\n");
				return 0;
				break;
		}
	}
Y más o menos este es el asunto. Simplificando todo esto llegué al fallo concreto, que básicamente es lo que expliqué en el primer post. Espero que ayude un poco más, pero la verdad que creo que esto lía un poco más la cosa.

PD: sobre los parámetros de fwrite, creo que la forma correcta es la mía, ya que el segundo parámetro es la longitud de cada elemento individual a escribir (un byte en mi caso, por lo tanto 1), y el tercer parámetro es el número de elementos, o sea, strlen(...).