Comment lire une chaîne de caractères à partir du clavier à l'aide de C?
Je veux lire une chaîne de caractères saisie par l'utilisateur. Je ne sais pas la longueur de la chaîne. Comme il n'existe pas de chaînes de caractères en C, j'ai déclaré un pointeur:
char * word;
et utilisé scanf
pour lire l'entrée à partir du clavier:
scanf("%s" , word) ;
mais j'ai une erreur de segmentation.
Comment puis-je lire l'entrée à partir du clavier en C lorsque la durée est inconnue ?
Vous devez vous connecter pour publier un commentaire.
Vous n'avez pas de stockage alloué pour
word
- c'est juste une balançant pointeur.Changement:
à:
Noter que 256 est un choix arbitraire, ici la taille de ce tampon doit être supérieure à la plus grande chaîne possible que vous pourriez rencontrer.
Note également que fgets est mieux (plus sûr), alors scanf pour la lecture des chaînes de longueur arbitraire, en ce qu'elle prend un
size
argument, ce qui aide à prévenir les dépassements de tampon:256
est entièrement arbitraire, de sorte que vous (bien, à 2½ ans) lui a appris à écrire des dépassements de mémoire tampon et d'énormes failles de sécurité. Félicitations.fgets
plutôt quescanf
de longueur arbitraire de la chaîne d'entrée.Je ne vois pas pourquoi il y a une recommandation de l'utilisation de
scanf()
ici.scanf()
est sûr que si vous ajoutez des paramètres de restriction de la chaîne de format comme%64s
ou donc.Une bien meilleure façon est d'utiliser
char * fgets ( char * str, int num, FILE * stream );
.(non testé)
stdin
, pasSTDIN
.Lors de la lecture d'entrée à partir de n'importe quel fichier (stdin inclus) où vous ne connaissez pas la longueur, il est souvent préférable d'utiliser
getline
plutôt quescanf
oufgets
parce quegetline
va gérer l'allocation de la mémoire pour votre chaîne automatiquement tant que vous fournir un pointeur null pour recevoir la chaîne entrée. Cet exemple permet d'illustrer:Les parties pertinentes en cours:
Réglage
line
àNULL
causes getline pour allouer de la mémoire automatiquement. Exemple de sortie:Donc, avec
getline
vous n'avez pas besoin de deviner combien de temps de l'utilisateur de votre chaîne sera.fgets
dans songetline
.... Bonne prise.fgets()
v.getline()
. Le illimitégetline()
, l'OMI est trop près d'un hacker exploiter, car il permet à l'externe fourni des données pour saturer un programme. Encore une mémoire tampon fixe (fgets()
) est trop restrictif. J'ai joué avec m'allocating un énorme tampon pourfgets()
et en s'appuyant sur *retard de répartition de l' de contrôler les choses.getline
à la mémoire tampon d'un868789
chaîne de caractères -- pas de plaintes. Je vais creuser dans votre retard allocation lien et voir ce que les perles/les risques sont là. Il n'y a tout simplement pas de remplacement pour la souplessegetline
offre. J'ai bricolé avec l'écriture de remplacement à l'aide defgetc
, mais la fin de la réécrituregetline
plus ou moins. La protection engetline
est le fait qu'elle continue de les répartir, à empêcher un dépassement, mais il met du fardeau de la preuve sur vous pour vérifier la taille du résultat de la vraisemblance...Ce code affiche la chaîne de caractères avec des lacunes, comme indiqué ci-dessus.
Vous avez besoin d'avoir le pointeur quelque part à l'utiliser.
Essayez ce code:
Cela crée un tableau de caractères de longueur 64 et le lit à l'entrée à elle. Notez que si l'entrée est de plus de 64 octets du mot tableau déborde et que votre programme n'est fiable.
Comme Jens a fait remarquer, il serait préférable de ne pas utiliser scanf pour lire des chaînes de caractères. Ce serait à l'abri de la solution.
scanf
en premier lieu de lire une chaîne de caractères; utilisationfgets
à la place qui prend un argument de longueur.fgets
déjà de zéro met fin à la chaîne d'entrée. Aussi, contrairement à*scanf
, elle ne représente que l'utilisation de la pleine taille de la matrice est idiomatiques:fgets(word, sizeof word, stdin)
fgets(word, 63, stdin); word[63] = 0;
-->fgets(word, sizeof word, stdin);