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;
}
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 +1
null
char). Donc la déclarer comme:
char words[16];
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;
}
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
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.
je suppose que la meilleure façon de le faire est ...
int main()
{
char str[100];
scanf("[^EOF]",str);
printf("%s",str);
return 0;
}
C Pour les utilisateurs, cela fonctionnera également
while ( gets(str) != NULL )