C, entrada estándar de lavado

3 minutos de lectura

C entrada estandar de lavado
doggydoo

tengo un problema con el uso de fgets. Se supone que el bucle debe leer una línea de máx. 19 caracteres, analice esta matriz de caracteres y luego espere la siguiente entrada. El problema es que si la línea ingresada supera los 19 caracteres, fgets llenará str con los caracteres restantes hasta que se ingrese Ctrl-D o nueva línea, iniciando así un nuevo ciclo sin nueva entrada. La entrada (stdin) debería vaciarse de alguna manera después de leer 19 caracteres, de modo que el ciclo pueda comenzar desde cero. Alguien tiene una solución para esto?

 char str[20];
 while((fgets(str, 20, stdin) != NULL)) {
  puts(str);        //monitoring str

  if(str[0] == 'q') break;
 }

Ejemplo en uso:

hola hola                        //user inputs 9 chars + newline
hola hola                        //puts writes

hoo hoo hoo hoo hooh             //user inputs 20 chars + newline
hoo hoo hoo hoo hoo              //puts writes
h                                //

scanf("%*[^\n]\n"); es probablemente una de las posibilidades más simples.

  • Supongo que debe pasar un argumento de búfer de caracteres. Esta solución no comprueba el desbordamiento del búfer, ¿verdad? Dios mío, mi C está tan oxidado.

    – xpmateo

    6 oct 2010 a las 19:33


  • @xpmatteo: no necesita un argumento de búfer. De man scanf: “Un carácter de supresión de asignación ‘*’ opcional: scanf() lee la entrada como se indica en la especificación de conversión, pero descarta la entrada. No se requiere ningún argumento de puntero correspondiente”

    – Giuseppe Cardone

    6 oct 2010 a las 19:37

  • Como señaló @Giuseppe, parte de la belleza de esto es que no tienes que pasar un búfer. Como no hay búfer, tampoco hay posibilidad de desbordamiento del búfer. Sin embargo, no se culpe por no reconocer esto: esta conversión definitivamente está en el lado esotérico.

    – Jerry Ataúd

    6 oct 2010 a las 19:40

  • Es necesario comprobar si la cadena que fgets() leer terminado con un \n primero, de lo contrario, leerá y descartará el próximo línea.

    – café

    6 oct 2010 a las 21:28

  • Probablemente quieras usar "%*[^\n]%*c" en lugar de "%*[^\n]\n". los \n no coincide con una nueva línea literal, sino que descarta cualquier cantidad de espacios en blanco hasta el siguiente carácter que no sea un espacio en blanco.

    – R.. GitHub DEJA DE AYUDAR A ICE

    6 oct 2010 a las 21:59

1646959267 842 C entrada estandar de lavado
fred foo

char str[21];  /* read one extra character */
while (fgets(str, 21, stdin) != NULL) {
    /* if line too long, truncate and swallow the rest of the line */
    if (strlen(str) > 19) {
        str[19] = '\0';
        while (getchar() != '\n' && !feof(stdin))
            ;
    }

    puts(str);
    if(str[0] == 'q') break;
}

Otra posible variante con la restricción de que fgets() sea la única entrada utilizada y a nivel de bucle. Definitivamente es muy similar a lo que propuso larsman. Así que supongo que votaré por él 🙂

#include <stdio.h>

int main(){
    char str[20];
    int skip = 0;
    str[19] = 1;
    while (fgets(str, 20, stdin)) {
        // just ignore lines of more than 19 chars
        if (str[19] == 0){
            str[19] = 1;
            skip = 1;
            continue;
        }
        // also skip the end of long lines
        if (skip) {
            skip = 0;
            continue;
        }
        // monitor input
        puts(str);
        // stop on any line beginning with 'q'
        if (str[0] == 'q'){
            break;
        }
    };
}

Echa un vistazo a fpurge:

fpurge(stdin);

C entrada estandar de lavado
xpmateo

Tratar:

fgets(str, 2000, stdin)

Luego trunca str a 19 🙂

  • … ¡y espero que el usuario nunca pegue una línea de 2 MB de largo!

    – Jerry Ataúd

    6 oct 2010 a las 19:42

  • Cierto 🙂 pero es una solución rápida.

    – xpmateo

    8 de octubre de 2010 a las 11:28

  • … ¡y espero que el usuario nunca pegue una línea de 2 MB de largo!

    – Jerry Ataúd

    6 oct 2010 a las 19:42

  • Cierto 🙂 pero es una solución rápida.

    – xpmateo

    8 de octubre de 2010 a las 11:28

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad