web-dev-qa-db-fra.com

Comment lire une chaîne de caractères en utilisant le C?

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?

48
mainajaved

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);
53
Paul R

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é)

18
glglgl

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.

15
David C. Rankin
#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.

4
Ananth Reddy

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;
1
Juho