Comment lire l'entrée standard dans une variable de chaîne jusqu'à ce que EOF en C?
J'obtiens "Erreur de Bus" en essayant de lire stdin
dans un char*
variable.
Je veux juste lire des trucs venant stdin
et de le mettre en premier dans une variable, puis continuer à travailler sur la variable.
Mon Code est comme suit:
char* content;
char* c;
while( scanf( "%c", c)) {
strcat( content, c);
}
fprintf( stdout, "Size: %d", strlen( content));
Mais de toute façon j'ai toujours "erreur de Bus" retournée par l'appel de cat test.txt | myapp
, où myapp
est le code compilé ci-dessus.
Ma question est comment puis-je lire stdin
jusqu'à ce que EOF dans une variable? Comme vous le voyez dans le code, j'ai juste envie d'imprimer la taille de l'entrée de venir sur stdin, dans ce cas, il doit être égale à la taille du fichier test.txt
.
Je pensais juste à l'aide de scanf
serait assez, peut-être tamponnée façon de lire stdin
?
OriginalL'auteur NovumCoder | 2010-03-23
Vous devez vous connecter pour publier un commentaire.
Tout d'abord, vous êtes de passage de pointeurs non initialisés, ce qui signifie
scanf
etstrcat
va écrire la mémoire ne vous appartient pas. Deuxièmement,strcat
attend deux null chaînes, alors que c est juste un personnage. Ce sera à nouveau la cause pour lire la mémoire ne vous appartient pas. Vous n'avez pas besoin de scanf, parce que tu ne fais pas de réel traitement. Enfin, la lecture d'un caractère est inutilement lente. Voici le début d'une solution, à l'aide d'un redimensionnable tampon pour la finale de la chaîne, et une mémoire tampon fixe pour le fgets appelEDIT: Comme Wolfer fait allusion, d'une valeur NULL dans votre entrée sera la cause de la chaîne à être mis fin prématurément lors de l'utilisation de fgets. getline est un meilleur choix si disponible, car il gère l'allocation de la mémoire et de ne pas avoir de problèmes avec NUL d'entrée.
invalid conversion from ‘void*’ to ‘char*’ [- fpermissive]
surchar *content = malloc(sizeof(char) * BUF_SIZE);
etcontent = realloc(content, contentSize);
avec gcc 4.8.1 ...Aussi il échoue lorsqu'ils sont présentés avec
0x00
dans stdin.gcc C compilateur a plus -fpermissive. Vous êtes peut-être le compiler en C++; qui pourrait expliquer l'erreur? Les balises dire C. Vous avez raison, fgets ne joue pas bien avec le NUL de caractères. Il ne provoque un comportement indéfini, mais vous ne savez pas, et la chaîne ne peut être mis fin prématurément. Je vais ajouter une remarque à propos de getline à la question.
Oups, my bad, désolé.
OriginalL'auteur Matthew Flaschen
Votre problème est que vous n'avez jamais alloué
c
etcontent
, ils ne sont donc pas pointer n'importe où définie -- ils sont susceptibles de pointage pour certains non alloué de la mémoire, ou de quelque chose qui n'existe pas du tout. Et puis vous mettez des données. Vous avez besoin de les affecter en premier. (Qu'est ce qu'une erreur de bus signifie généralement, vous avez essayé de faire un accès à la mémoire n'est pas valide.)(Alternativement, depuis
c
est toujours tenue un seul personnage, vous pouvez la déclarer commechar c
et passer&c
à scanf. Pas besoin de déclarer une chaîne de caractères lorsque l'on va faire).Une fois que vous faites cela, vous allez rencontrer le problème de faire en sorte que
content
est assez long pour contenir tous les commentaires. Soit vous avez besoin d'avoir une estimation de combien de saisie que vous attendez et de l'allouer au moins que long (et puis d'erreur si vous dépassez ce), ou vous avez besoin d'un stratégie de réaffecter les fonds dans une taille plus grande si elle n'est pas assez long.Oh, et vous aurez également exécuter dans le problème que
strcat
attend une chaîne, pas un seul caractère. Même si vous laissezc
comme unchar*
, lescanf
appel n'est pas une chaîne. Une seule chaîne de caractères est (de mémoire) un personnage suivie par un caractère null pour indiquer la fin de la chaîne.scanf
, lors de la numérisation d'un seul caractère, n'est pas à mettre dans le caractère null après. En conséquence,strcpy
ne va pas savoir où la fin de la chaîne est, et continuera d'aller balader à travers la mémoire à la recherche pour le caractère null.+1 @Matthieu, sauf si elles sont globales.
juste faire
c
unchar
et à l'aide de&c
n'est pas assez, depuisstrcat()
a besoin d'une chaîne se terminant par null.Carl: Merci, je viens d'ajouter que. Matthieu, merci pour le commentaire; je vais éditer pour ajouter.
OriginalL'auteur Brooks Moses
Puisque vous n'avez pas de soins sur le contenu réel, pourquoi la peine à construire une chaîne de caractères? Je voudrais aussi utiliser
getchar()
:Ce code permet de gérer correctement le cas où votre dossier a
'\0'
caractères.c
doivent être déclarés commeint
pour inclure la gamme dechar
plusEOF
.ouais, bon appel. Taper sans réfléchir.
Je dois avoir manqué que lors de la lecture. Je pense que la réponse se présente comme un exemple quand même raisonnable.
Carl: D'Accord. (Et upvoted.)
OriginalL'auteur Carl Norum
Le problème ici est que vous faites référence à un pointeur de variable qui n'mémoire allouée par
malloc
, d'où les résultats seraient pas défini, et de ne pas être seul, à l'aide destrcat
sur un indéfini pointeur peut pointer sur n'importe quoi, vous vous retrouviez avec une erreur de bus!Ce serait le code fixe requis....
Le code met en évidence le programmeur responsable de la gestion de la mémoire - pour chaque
malloc
il y a unfree
si non, vous avez une fuite de mémoire!Edit: Grâce à David Gelhar son point-à mon problème! J'ai corrigé le code ci-dessus afin de refléter les corrections...bien sûr, dans une situation de vie réelle, peut-être la valeur fixe de 100 pourrait être changé pour peut-être un
#define
pour le rendre facile à étendre la mémoire tampon par un doublement de la quantité de mémoire viarealloc
et de l'assiette de la taille...Comme Jon Purdy noté sur l'un des autres postes, vous devez déclarer c comme int, pas de char, de sorte que les expressions du FOLKLORE résultat sera à portée. Sinon, vous allez entrer dans une boucle infinie. Aussi, votre strcat appel attend deux null chaînes, pas une chaîne de caractères et un caractère unique. Comme l'a écrit, il ne compile pas.
OriginalL'auteur t0mm13b
En supposant que vous souhaitez obtenir (plus courte que MAXL-1 caractères) les chaînes de caractères et de ne pas traiter votre fichier char par char, j'ai fait comme suit:
OriginalL'auteur user3715859