Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

433
Views
Leer desde stdin con fgets, error si la entrada es mayor que el tamaño

Estoy creando una aplicación de línea de comandos con un aviso. Funciona bien siempre que la entrada quepa dentro del búfer, pero cuando la entrada es más grande, obtengo un comportamiento extraño. A continuación se muestra un ejemplo mínimo simplificado que tiene el mismo error.

 int main() { for (;;) { const int size = 8; char str[size]; printf("> "); fgets(str, size, stdin); toupper_str(str); printf("Result: %s\n", str); } }

Funciona bien si la entrada es más pequeña que size .

 > asdf Result: ASDF >

Cuando la entrada es más grande, la parte de la entrada en el rango se procesa y, en la siguiente iteración del bucle, fgets inmediatamente el resto de la entrada dada. Esto lleva a que esa parte de la entrada también se procese y a una salida extraña.

 > asdfghjk Result: ASDFGHJ > Result: K >

Puedo ver si la entrada es mayor o igual al tamaño comparando el último carácter con una nueva línea. fgets retiene la nueva línea mientras quepa.

 fgets(str, size, stdin); if (str[strlen(str) - 1] != '\n') { fprintf(stderr, "Input too long\n"); }

Cuando se detecta esto, ¿cómo evito que lea el resto de la entrada demasiado larga en la siguiente iteración?

He visto preguntas similares aquí, pero ninguna que haga la misma pregunta.

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

¿Cómo evito que lea el resto de la entrada demasiado larga en la siguiente iteración?

El código necesita 1) detectar si la entrada es "demasiado larga" 2) consumir la entrada adicional.

fgets() no sobrellenará el búfer. Si llena el búfer, el último char en el búfer es '\0' . Así que configúralo como no '\0' antes de leer. Luego, el código sabe si se llenó todo el búfer. Luego verifique si el char anterior era un '\n' . Si no es un final de línea, puede existir un char adicional en stdin

 char str[100]; // Insure buffer is at least size 2 for (;;) { str[sizeof str - 1] = `x`; if (fgets(str, size, stdin) == NULL) { // No more to read or IO error break; } int extra_data_found = 0; if (str[sizeof str - 1] == '\0' && str[sizeof str - 2] != '\n') { // Cope with potential extra data in `stdin`: read and toss int ch; while ((ch = fgetc(stdin)) != '\n' && ch != EOF) { extra_data_found = 1; } } // Use `str` as needed, noting if additional unsaved data found foo(str, extra_data_found); }

Nota: en un error de archivo, fgets() devuelve NULL y el contenido de str no está definido.

Nota: En lugar de str[sizeof str - 1] == '\0' , el código podría usar strlen(str) == sizeof str - 1 . Esto se engaña si fgets() lee un carácter nulo '\0' .

Casos de esquina:
1. La str típica tendrá hasta 98 char y luego '\n' y '\0' . ¿Está bien si la última str tiene 99 char y luego '\0' ?
2. Si #1 está bien, ¿entonces una str típica puede tener 99 char y luego '\0' ?

over 4 years ago · Santiago Trujillo Report

0

Cuando la entrada es demasiado larga, debe leer los caracteres restantes en la entrada estándar antes de continuar con la siguiente iteración del ciclo.

 if (fgets(str, size, stdin) == NULL) { if (feof(stdin)) { return 0; else { perror("Could not read from stdin"); exit(1); } } else if (strchr(str, '\n') == NULL) { int c; while((c = getc(stdin)) != '\n' && c != EOF); fprintf(stderr, "Input too long\n"); }

Si está en un sistema POSIX como OS X o Linux, ya existe la función getline que lee una cadena terminada en una nueva línea de longitud arbitraria de una secuencia. También puede encontrar muchas versiones gratuitas/de código abierto de esta función en línea.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!