fgets lee demasiados caracteres que existe
Pregunta
Tengo la siguiente función:
void writeResults(FILE* fp, FILE* fpw, Vector w, int size) {
Vector x;
while (1) {
char line[MAX_DIMENSION]; //max dimension is 200
if( (fgets(line,MAX_DIMENSION,fp)) == NULL) { //EOF
return;
}
else {
int i=0;
while (line[i]!='\0') {
printf("% d %c\n",i,line[i]); //print to check it
i++;
}
}
}
}
La línea del archivo se lee es:
1,1
2,2
Sin embargo, cuando imprimo cada carbón hasta '\ 0' consigo esta salida:
0 1
1 ,
2 1
3
4
0 2
1 ,
2 2
3
4
¿Alguien tiene una idea de por qué se lee el extra de 3 y 4 caracteres? (No hay espacios adicionales en el archivo).
Nota: el archivo fue abierto de la siguiente manera:
FILE* fp = fopen(fileIn, "r");
if (fp == NULL) {
perror("Couldn't open File");
exit(errno);
}
Solución
Retorno de carro, línea de alimentación - en Windows
Sería de gran ayuda si sabíamos cómo se abre el archivo. Si ha abierto como un archivo de texto, entonces no debería estar viendo los dos personajes extra - sólo uno para la nueva línea. Sin embargo, si se abre como un archivo binario, que de hecho debe leer tanto la CR y el LF.
Si está en Linux, como se indica en los comentarios, entonces tenemos más herramientas de diagnóstico disponibles. Tal vez el más simple es comenzar con 'od -c file
'; esto le mostrará exactamente lo que está en el archivo. Tenga en cuenta que si el archivo fue alguna vez en una máquina Windows, todavía podría tener los finales de línea CRLF. Si utiliza 'vim', se podría decir que el tipo de archivo es '[DOS]'.
Como alternativa, puede imprimir los caracteres como números enteros (así como caracteres):
printf("%d (%2d) %c\n", i, line[i], line[i]);
Debería ver 49 para '1', 50 para '2', 44 para '', 10 para salto de línea (LF, '\n
'), y también algo más - que es el misterio (pero sería una muestra de 13 para CR).
CR es el carácter \r
en C fuente. Se utiliza para indicar que el cabezal de impresión debe moverse de nuevo al comienzo de la línea (carro de la impresora vuelto a inicio de la línea); la alimentación LF o línea de desplazar el papel una línea. Windows y MS-DOS ambos utilizan el CRLF (curr-liff) secuencia para indicar un final de línea; Unix siempre se utiliza simplemente LF, también conocido como salto de línea o de NL; MacOS 9 y utilizado anteriormente solo CR.
Otros consejos
no imprima% c, d imprimir% y verá el código de caracteres ASCII. se dará cuenta de que los personajes son retorno de carro y avance de línea. 13 y 10
consulte http://www.asciitable.com/
Creo que el archivo de entrada contiene -
1,1
[SPACESPACE]
2,2
[SPACESPACE]
Así que primero fgets tiempo se leen como -
line{'1',',','1','',''}
y la segunda vez lee
line{'2',',','2','',''}
es por eso, que está recibiendo de salida según lo especificado