8
votes

Lire un nombre inconnu d'entiers de stdin (c)

J'ai besoin de lire un fichier d'entrée comme: xxx

chaque ligne étrange est un entier. Chaque ligne paire est un nombre inconnu d'entiers.

Il est très facile en C ++ xxx

Je ne suis pas aussi habitué à c, donc je ne pouvais pas faire en C. Toute façon de le faire?


3 commentaires

Devez-vous faire attention aux lignes ou est-ce qu'une série d'entiers entrant? Dans votre exemple, on dirait que les lignes impaires sont des numéros de séquence et les lignes même représentent autre chose.


David, j'ai besoin de faire attention aux lignes. C'est pourquoi je ne pouvais pas le faire. Je dois arrêter d'obtenir de nouvelles valeurs à la fin de chaque ligne même. Parce que j'ai une structure avec ID d'attributs et liste. Chaque ligne étrange est un identifiant et chaque ligne pair est une liste. Je veux remplir une structure avec 2 lignes de données et déplacer vers une autre structure et le remplir avec 2 autres lignes de données, etc.


Lire dans une ligne entière à la fois, puis juste analyser comme une chaîne


6 Réponses :


12
votes

Exécution de votre fichier d'entrée via:

read number: 1
read number: 19
read number: 20
read number: 41
read number: 23
read number: 2
read number: 41
read number: 52
read number: 43
read number: 3
read number: 90
read number: 91
read number: 941
read number: 4
read number: 512
read number: 5
read number: 6
read number: 51
read number: 61


1 commentaires

Je peux lire la ligne correctement mais la boucle Scanf imprime infiniment le premier numéro pour moi.



0
votes

Regardez GetC (3) ou Scanf (3)


0 commentaires

10
votes

La façon dont je voudrais le faire est de le casser dans deux opérations: lisez une ligne, puis lisez les entiers de cette ligne. Voici une implémentation paresseuse utilisant la bibliothèque C standard C: xxx


6 commentaires

Merci beaucoup. Je vais essayer maintenant. Mais si je ne peux pas supposer une longueur de ligne maximale fixe?


Et si le flux d'entrée contient plus de 1024 - 2 caractères et fgets () divise le flux d'entrée à un littéral numérique? Vous vous retrouverez avec deux valeurs numériques au lieu d'un. Par exemple, à partir de 12345, vous pouvez obtenir 123 dans la dernière itération de la boucle for-boucle et 45 dans la première itération de la boucle de commande après le prochain appel de fgets () . Par conséquent, je préférerais scanf () et FSCANF () pour cette tâche, comme indiqué par Sean.


@RobinkLose: la solution scanf () Publié par Sean ne résout pas le problème, car elle ne distingue pas les pauses de la ligne d'autres espaces.


@Dietrichepp: OK, je vois ton point. Le questionneur devait garder une trace des lignes. Mais voyez-vous un moyen simple de se débarrasser du problème que j'ai décrit ci-dessus?


@RobinkLose: Je ne connais aucune solution complète, simple et portable dans C. La solution ci-dessus est incomplète. Utilisation de getchar () pour analyser les entiers sans tampon intermédiaire est complexe. En utilisant getline () n'est pas portable. Et enfin, vous pouvez le faire dans Python assez facilement, mais ce n'est pas la meilleure chose à faire, si vous ne pouvez pas garantir des lignes plus courtes qu'un grand nombre, et que vous ne pouvez pas utiliser Python, est d'écrire votre propre Version de getline () .


Notez que getline () fait partie de la norme POSIX, elle n'est tout simplement pas disponible sous Windows.



1
votes

Je ferais l'un des:

  • fgetc.) Pour lire des caractères individuels et les analyser vous-même (accumulez des chiffres jusqu'à ce que vous appuyez sur des espaces et que vous avez un entier à convertir avec ATOI (); si le blancheur est une nouvelle ligne, il terminait une liste d'entiers )

  • fgets () pour lire une ligne à la fois, puis analyser la chaîne (à nouveau, recherchez des espaces qui séparent les valeurs) qu'il renvoie.


0 commentaires

3
votes

Je briserais le programme dans différentes tâches.

La première étape consiste à être capable de lire une paire de lignes, la première ligne qui vous indique le nombre de chiffres à lire, puis la deuxième ligne pour lire la nombres réels. Pour cela, une fonction appelée quelque chose comme read_set pourrait être utile. Il devrait être en mesure de renvoyer les chiffres lire et de signaler la fin du fichier ainsi que des erreurs. Pour cela, nous pouvons définir une structure de données telle que: xxx

, puis nous pouvons déclarer notre fonction avec le prototype: xxx

La fonction allouera la mémoire pour num-> données et définir num-> len à la valeur correcte. Il retourne 0 pour réussir et un ensemble de conditions d'erreur autrement. Nous pourrions avoir envie et utiliser un Enum pour les statuts de retour ultérieurement. Pour le moment, disons que 0 = succès, 1 = fin du fichier, et tout le reste est une erreur.

L'appelant appelle alors lis_set () dans une boucle: xxx

pour implémenter read_set () : il doit lire deux lignes. Il y a beaucoup implémentations de la lecture d'une ligne complète en C , de sorte que vous Peut utiliser l'un d'entre eux et lire une ligne d'abord, puis sscanf () / strtoul () pour un numéro (cochez sa valeur de retour!). Une fois que vous avez le nombre de chiffres, n , vous pouvez lire la ligne suivante en mémoire et faire: xxx

Vous pouvez alors appeler à plusieurs reprises < Code> SSCANF () ou STRTOL () Pour stocker les numéros dans Num-> Data . Vous devez faire des chèques pour vous assurer que exactement n sont sur cette ligne.

Notez que vous pouvez écrire read_set () d'une autre manière aussi: Lisez un caractère de ligne par caractère et analysez les chiffres lorsque vous les lisez. Cela n'a l'avantage de passer sur les données qu'une seule fois, et de ne pas avoir besoin d'un gros tampon pour stocker toute la ligne d'entrée en mémoire, mais l'inconvénient est de faire des trucs de faible niveau et de lire des données caractéristiques par caractère peut être lente. < / p>


0 commentaires

1
votes

Je suis venu avec une solution comme celle-ci: XXX


0 commentaires