Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

439
Visualizações
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 Respostas
Responde à pergunta

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda