Su ciclo tiene varios problemas. Usted escribió:
while(fscanf(f, "%[^\n\r]s", cLine) != EOF)
/* do something */;
Algunas cosas a considerar:
fscanf() devuelve el número de elementos almacenados. Puede devolver EOF si lee más allá del final del archivo o si el identificador del archivo tiene un error. Debe distinguir una devolución válida de cero, en cuyo caso no hay contenido nuevo en el almacenamiento intermedio cLine
de una lectura correcta.
Tiene un problema cuando falla la coincidencia porque es difícil predecir hacia dónde apunta el archivo en la transmisión. Esto hace que la recuperación de un partido fallido sea más difícil de lo que podría esperarse.
El patrón que escribió probablemente no hace lo que pretendía. Está haciendo coincidir cualquier número de caracteres que no son CR o LF, y luego espera encontrar un literal s
.
No ha protegido su memoria intermedia de un desbordamiento. Se puede leer cualquier cantidad de caracteres del archivo y escribir en el búfer, independientemente del tamaño asignado a ese búfer. Este es un error desafortunadamente común, que en muchos casos puede ser explotado por un atacante para ejecutar código arbitrario de los atacantes que elijan.
A menos que haya solicitado específicamente que f
se abra en modo binario, la traducción de final de línea se realizará en la biblioteca y, en general, nunca verá caracteres CR, y generalmente no en archivos de texto.
es probable que desee un bucle más como el siguiente:
while(fgets(cLine, N_CLINE, f)) {
/* do something */ ;
}
donde N_CLINE es el número de bytes disponibles en el tampón de partida un cLine
.
La función fgets()
es una forma muy preferida de leer una línea de un archivo. Su segundo parámetro es el tamaño del búfer, y lee hasta 1 bytes menos que el tamaño del archivo en el búfer. Siempre termina el búfer con un carácter nul
para que pueda pasar con seguridad a otras funciones de cadena C.
Se detiene en el primero del final del archivo, nueva línea o buffer_size-1
bytes leídos.
Deja el carácter de nueva línea en el búfer, y ese hecho le permite distinguir una única línea más larga que su búfer de una línea más corta que el búfer.
Devuelve NULL si no se copiaron bytes debido al final del archivo o un error, y el puntero al búfer en caso contrario. Es posible que desee utilizar feof()
y/o ferror()
para distinguir esos casos.
[^ a-z] realmente excluye a-z en scanf. Aunque, la cadena como se indicó anteriormente, busca "un par de caracteres, el primero no es un salto de línea, y el segundo es un" – Tordek
La documentación de fscanf en cplusplus.com está incompleta. Google 'fscanf scanset'. – Dingo