Comment lire scanf jusqu'à EOF en C?

j'ai ceci mais une fois qu'il atteint l'EOF supposée il répète juste la boucle et scanf encore.

int main(void)
{
        char words[16];

        while(scanf("%15s", words) == 1)
           printf("%sn", words);

        return 0;
}
28
demandé sur JJRhythm 2010-09-22 00:03:50

6 réponses

Essaie:

while(scanf("%15s", words) != EOF)

vous devez comparer scanf sortie EOF

Puisque vous spécifiez une largeur 15 dans la chaîne de format, vous lirez au plus 15 caractères. Les mots char tableau doit être de taille 16 ( 15 +1null char). Donc la déclarer comme:

char words[16];
18
répondu codaddict 2010-09-21 20:09:50

Scanf est à peu près toujours plus problématique que sa valeur. Voici les deux meilleures façons de faire ce que vous essayez de faire. Cette première est une traduction plus ou moins directe de votre code. Il est plus long, mais vous pouvez le regarder et voir clairement ce qu'il fait, contrairement à scanf.

#include <stdio.h>
#include <ctype.h>
int main(void)
{
    char buf[1024], *p, *q;
    while (fgets(buf, 1024, stdin))
    {
        p = buf;
        while (*p)
        {
            while (*p && isspace(*p)) p++;
            q = p;
            while (*q && !isspace(*q)) q++;
            *q = '';
            if (p != q)
                puts(p);
            p = q;
        }
    }
    return 0;
}

Et voici une autre version. Il est un peu plus difficile de voir ce que cela fait par inspection, mais il ne casse pas si une ligne est plus longue que 1024 caractères, donc c'est le code que j'utiliserais dans production. (Eh bien,vraiment ce que j'utiliserais dans la production est tr -s '[:space:]' '\n', mais c'est comme ça qu'on implémente quelque chose comme ça.)

#include <stdio.h>
#include <ctype.h>
int main(void)
{
    int ch, lastch = '';
    while ((ch = getchar()) != EOF)
    {
        if (!isspace(ch))
            putchar(ch);
        if (!isspace(lastch))
            putchar('\n');
        lastch = ch;
    }
    if (lastch != '' && !isspace(lastch))
        putchar('\n');
    return 0;
}
3
répondu zwol 2010-09-22 15:57:18

vos boucles de code jusqu'à ce qu'elles lisent un seul mot, puis sortent. Donc, si vous donnez plusieurs mots, il va lire la première et de sortie, tandis que si vous lui donnez une entrée vide, il va boucler indéfiniment. Dans tous les cas, il n'imprimera que des déchets aléatoires de mémoire non initialisée. Ce n'est apparemment pas ce que vous voulez, mais que voulez-vous? Si vous voulez juste lire et imprimer le premier mot (s'il existe), utilisez si:

if (scanf("%15s", word) == 1)
    printf("%s\n", word);

Si vous souhaitez en boucle aussi longtemps que vous pouvez lire un mot, utilisez alors que:

while (scanf("%15s", word) == 1)
    printf("%s\n", word);

en outre, comme d'autres l'ont noté, vous devez donner au tableau de mot une taille qui est assez grande pour votre scanf:

char word[16];

D'autres ont suggéré de tester EOF au lieu de vérifier combien d'éléments scanf correspondait. C'est très bien pour ce cas, où scanf ne peut pas manquer de correspondre à moins qu'il y ait un EOF, mais n'est pas si bon dans d'autres cas (comme essayer de lire des entiers), où scanf pourrait correspondre à rien sans atteindre L'EOF (si l'entrée n'est pas un nombre) et retourner 0.

modifier

on dirait que vous avez changé votre question pour correspondre à mon code qui fonctionne bien quand je l'exécute -- boucles de lecture de mots jusqu'à ce que EOF soit atteint et puis sort. Donc quelque chose d'autre se passe avec votre code, peut-être lié à la façon dont vous l'alimentez comme suggéré par David

3
répondu Chris Dodd 2010-09-23 16:50:54

Vous devez vérifier la valeur de retour contre EOF, pas contre 1.

notez que dans votre exemple, vous avez aussi utilisé deux noms de variables différents,words et word, seulement déclaré words, et n'a pas déclaré sa longueur, qui devrait être de 16 pour correspondre aux 15 caractères lus dans plus un NUL personnage.

0
répondu Brian Campbell 2010-09-21 20:09:21

je suppose que la meilleure façon de le faire est ...

int main()
{
    char str[100];
    scanf("[^EOF]",str);
    printf("%s",str);
    return 0;     
}
-1
répondu Codercool 2013-12-05 14:16:03

C Pour les utilisateurs, cela fonctionnera également

while ( gets(str) != NULL )
-3
répondu Psycho 2013-01-21 18:18:47