¿Cuál es la forma más fácil de contar las nuevas líneas en un archivo ASCII?

¿Cuál es la forma más rápida de obtener las líneas de un archivo ASCII?

Normalmente lees archivos en C usando fgets . También puede usar scanf("%[^\n]") , pero es probable que algunas personas que lean el código lo encuentren confuso y extraño.

Edición: por otro lado, si solo quiere contar las líneas, una versión ligeramente modificada del enfoque scanf puede funcionar bastante bien:

 while (EOF != (scanf("%*[^\n]"), scanf("%*c"))) ++lines; 

La ventaja de esto es que con el ‘*’ en cada conversión, scanf lee y coincide con la entrada, pero no hace nada con el resultado. Eso significa que no tenemos que desperdiciar la memoria en un búfer grande para contener el contenido de una línea que no nos importa (y aún así tener la oportunidad de obtener una línea que es incluso más grande que eso, por lo que nuestra cuenta termina mal) a menos que tengamos que trabajar aún más para averiguar si la entrada que leímos terminó con una nueva línea).

Desafortunadamente, tenemos que dividir el scanf en dos partes como esta. scanf detiene el escaneo cuando falla una conversión, y si la entrada contiene una línea en blanco (dos líneas nuevas consecutivas), esperamos que la primera conversión falle. Sin embargo, incluso si eso falla, queremos que ocurra la segunda conversión, para leer la próxima nueva línea y pasar a la siguiente línea. Por lo tanto, intentamos la primera conversión para “comer” el contenido de la línea, y luego hacemos la conversión %c para leer la nueva línea (la parte que realmente nos importa). Continuamos haciendo ambas cosas hasta que la segunda llamada a scanf devuelva EOF (que normalmente estará al final del archivo, aunque también puede ocurrir en caso de que se produzca un error de lectura).

Edit2: Por supuesto, hay otra posibilidad que es (al menos posiblemente) más simple y más fácil de entender:

 int ch; while (EOF != (ch=getchar())) if (ch=='\n') ++lines; 

La única parte de esto que algunas personas encuentran contraintuitiva es que ch debe definirse como un int , no un char para que el código funcione correctamente.

Aquí hay una solución basada en fgetc () que funcionará para líneas de cualquier longitud y no requiere que asignes un búfer.

 #include  int main() { FILE *fp = stdin; /* or use fopen to open a file */ int c; /* Nb. int (not char) for the EOF */ unsigned long newline_count = 0; /* count the newline characters */ while ( (c=fgetc(fp)) != EOF ) { if ( c == '\n' ) newline_count++; } printf("%lu newline characters\n", newline_count); return 0; } 

Tal vez me esté perdiendo algo, pero por qué no simplemente:

 #include  int main(void) { int n = 0; int c; while ((c = getchar()) != EOF) { if (c == '\n') ++n; } printf("%d\n", n); } 

si desea contar líneas parciales (es decir, [^ \ n] EOF):

 #include  int main(void) { int n = 0; int pc = EOF; int c; while ((c = getchar()) != EOF) { if (c == '\n') ++n; pc = c; } if (pc != EOF && pc != '\n') ++n; printf("%d\n", n); } 

Común, ¿por qué comparas todos los personajes? Es muy lento. En el archivo de 10 MB es ~ 3s.
Bajo solución es más rápido.

 unsigned long count_lines_of_file(char *file_patch) { FILE *fp = fopen(file_patch, "r"); unsigned long line_count = 0; if(fp == NULL){ return 0; } while ( fgetline(fp) ) line_count++; fclose(fp); return line_count; } 

Que hay de esto

 #include  #include  #define BUFFER_SIZE 4096 int main(int argc, char** argv) { int count; int bytes; FILE* f; char buffer[BUFFER_SIZE + 1]; char* ptr; if (argc != 2 || !(f = fopen(argv[1], "r"))) { return -1; } count = 0; while(!feof(f)) { bytes = fread(buffer, sizeof(char), BUFFER_SIZE, f); if (bytes <= 0) { return -1; } buffer[bytes] = '\0'; for (ptr = buffer; ptr; ptr = strchr(ptr, '\n')) { ++count; ++ptr; } } fclose(f); printf("%d\n", count - 1); return 0; }