64 votes

Comment lire une chaîne de caractères à partir du clavier en utilisant le C ?

Je veux lire une chaîne de caractères saisie par l'utilisateur. Je ne connais pas la longueur de cette chaîne. Comme il n'y a pas de chaîne de caractères en C, j'ai déclaré un pointeur :

char * word;

et utilisé scanf pour lire les entrées du clavier :

scanf("%s" , word) ;

mais j'ai un défaut de segmentation.

Comment puis-je lire une entrée du clavier en C lorsque la longueur est inconnue ?

71voto

Paul R Points 104036

Vous n'avez pas de stockage alloué pour word - c'est juste un pointeur flottant .

Changez :

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 pourriez rencontrer.

Notez également que fgets est une meilleure option (plus sûre) que scanf pour la lecture de chaînes de longueur arbitraire, en ce sens qu'elle prend un fichier size qui, à son tour, permet d'éviter les débordements de mémoire tampon :

 fgets(word, sizeof(word), stdin);

27voto

glglgl Points 35668

Je ne vois pas pourquoi il y a une recommandation d'utiliser scanf() ici. scanf() n'est sûr que si vous ajoutez des paramètres de restriction à la chaîne de format - tels que %64s ou plus.

Une bien meilleure solution 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é)

6 votes

Faites que stdin pas STDIN .

23voto

David C. Rankin Points 2674

Lors de la lecture d'entrées provenant de n'importe quel fichier (stdin inclus) dont vous ne connaissez pas la longueur, il est souvent préférable d'utiliser getline plutôt que scanf o fgets parce que getline se chargera automatiquement de l'allocation de mémoire pour votre chaîne de caractères, tant que vous fournissez un pointeur nul pour recevoir la chaîne saisie. Cet exemple en est une illustration :

#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 concernées étant :

char *line = NULL;  /* forces getline to allocate with malloc */
size_t len = 0;     /* ignored when line = NULL */
/* snip */
read = getline (&line, &len, stdin);

Réglage de line a NULL fait en sorte que getline alloue 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

Ainsi, avec getline vous n'avez pas besoin de deviner la longueur de la chaîne de caractères de votre utilisateur.

4voto

Ananth Reddy Points 101
#include<stdio.h>

int main()
{
    char str[100];
    scanf("%[^\n]s",str);
    printf("%s",str);
    return 0;
}

input : lire la chaîne de caractères
ouput : imprime la chaîne de caractères

Ce code imprime la chaîne de caractères avec des espaces comme indiqué ci-dessus.

3voto

Juho Points 923

Il faut que le pointeur pointe quelque part pour l'utiliser.

Essayez ce code :

char word[64];
scanf("%s", word);

Cette opération crée un tableau de caractères de longueur 64 et lit les données qui y sont entrées. Notez que si l'entrée est plus longue que 64 octets, le tableau de mots 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 les chaînes de caractères. Ce serait une solution sûre.

char word[64]
fgets(word, 63, stdin);
word[63] = 0;

2 votes

C'est pourquoi vous ne devriez pas utiliser scanf en premier lieu pour lire une chaîne de caractères ; utilisez fgets à la place, qui prend un argument de longueur.

0 votes

@Jens : Vous avez raison et je devrais avoir honte de ne pas avoir fourni une meilleure solution au départ. J'ai édité ma réponse au cas où quelqu'un viendrait la lire.

1 votes

fgets déjà zéro termine la chaîne d'entrée. En outre, contrairement à *scanf il en tient compte, de sorte que l'utilisation de la taille complète du tableau est idiomatique : fgets(word, sizeof word, stdin)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X