Je veux lire une chaîne entrée par l'utilisateur. Je ne connais pas la longueur de la chaîne. Comme il n'y a pas de chaînes en C, j'ai déclaré un pointeur:
char * Word;
et utilisé scanf
pour lire les entrées au clavier:
scanf("%s" , Word) ;
mais j'ai une faute de segmentation.
Comment lire une entrée du clavier en C quand la longueur est inconnue?
Vous n'avez pas de mémoire allouée pour Word
- c'est juste un pointeur qui pend .
Changement:
char * Word;
à:
char Word[256];
Notez que 256 est un choix arbitraire ici - la taille de ce tampon doit être supérieure à la plus grande chaîne possible que vous puissiez rencontrer.
Notez également que fgets est une meilleure option (plus sûre) que scanf pour lire des chaînes de longueur arbitraire, dans la mesure où il faut un argument size
, ce qui aide à son tour. pour empêcher les débordements de tampon:
fgets(Word, sizeof(Word), stdin);
Je ne vois pas pourquoi il est recommandé d'utiliser scanf()
ici. scanf()
n'est sécurisé que si vous ajoutez des paramètres de restriction à la chaîne de formatage, tels que %64s
ou plus.
Un meilleur moyen consiste à utiliser char * fgets ( char * str, int num, FILE * stream );
.
int main()
{
char data[64];
if (fgets(data, sizeof data, stdin)) {
// input has worked, do something with data
}
}
(non testé)
Lorsque vous lisez des entrées 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 que scanf
ou fgets
car getline
gérera automatiquement l'allocation de mémoire pour votre chaîne tant que vous fournissez un pointeur nul pour recevoir la chaîne entrée. Cet exemple illustrera:
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char *argv[]) {
char *line = NULL; /* forces getline to allocate with malloc */
size_t len = 0; /* ignored when line = NULL */
ssize_t read;
printf ("\nEnter string below [ctrl + d] to quit\n");
while ((read = getline(&line, &len, stdin)) != -1) {
if (read > 0)
printf ("\n read %zd chars from stdin, allocated %zd bytes for line : %s\n", read, len, line);
printf ("Enter string below [ctrl + d] to quit\n");
}
free (line); /* free memory allocated by getline */
return 0;
}
Les parties pertinentes étant:
char *line = NULL; /* forces getline to allocate with malloc */
size_t len = 0; /* ignored when line = NULL */
/* snip */
read = getline (&line, &len, stdin);
Définir line
sur NULL
force getline à allouer automatiquement de la mémoire. Exemple de sortie:
$ ./getline_example
Enter string below [ctrl + d] to quit
A short string to test getline!
read 32 chars from stdin, allocated 120 bytes for line : A short string to test getline!
Enter string below [ctrl + d] to quit
A little bit longer string to show that getline will allocated again without resetting line = NULL
read 99 chars from stdin, allocated 120 bytes for line : A little bit longer string to show that getline will allocated again without resetting line = NULL
Enter string below [ctrl + d] to quit
Donc, avec getline
, vous n'avez pas besoin de deviner la longueur de la chaîne de votre utilisateur.
#include<stdio.h>
int main()
{
char str[100];
scanf("%[^\n]s",str);
printf("%s",str);
return 0;
}
entrée: lire la chaîne
ouput: affiche la chaîne
Ce code imprime la chaîne avec des espaces, comme indiqué ci-dessus.
Vous devez avoir le pointeur pour pointer quelque part pour l'utiliser.
Essayez ce code:
char Word[64];
scanf("%s", Word);
Cela crée un tableau de caractères de lenth 64 et lit les entrées. Notez que si l'entrée est supérieure à 64 octets, le tableau Word déborde et votre programme devient peu fiable.
Comme Jens l'a souligné, il serait préférable de ne pas utiliser scanf pour lire des chaînes. Ce serait une solution sûre.
char Word[64]
fgets(Word, 63, stdin);
Word[63] = 0;