web-dev-qa-db-fra.com

Comment faire scanf pour un seul caractère en C

En C: J'essaie d'obtenir le caractère de l'utilisateur avec scanf et quand je l'exécute, le programme n'attend pas que l'utilisateur tape quoi que ce soit ...

C'est le code:

char ch;
printf("Enter one char");
scanf("%c", &ch);
printf("%c\n",ch);

Pourquoi ne fonctionne pas?

71
Yuval

Le spécificateur de conversion %c n'ignorera pas automatiquement les espaces de début, de sorte que s'il existe une nouvelle ligne perdue dans le flux d'entrée (à partir d'une entrée précédente, par exemple), l'appel scanf le consommera immédiatement.

Une solution au problème consiste à insérer un espace avant le spécificateur de conversion dans la chaîne de formatage:

scanf(" %c", &c);

Le blanc dans la chaîne de format indique à scanf de sauter les espaces, et le premier caractère non-blanc sera lu avec le spécificateur de conversion %c

190
John Bode

Tout d'abord, évitez scanf(). L'utiliser ne vaut pas la peine.

Voir: Pourquoi tout le monde dit de ne pas utiliser scanf? Que devrais-je utiliser à la place?

L'utilisation d'un caractère d'espacement dans scanf() ignorerait le nombre de caractères d'espacement restant dans le flux d'entrée. Que se passe-t-il si vous devez lire plus d'entrées? Considérer:

#include <stdio.h>

int main(void)
{
   char ch1, ch2;

   scanf("%c", &ch1);  /* Leaves the newline in the input */
   scanf(" %c", &ch2); /* The leading whitespace ensures it's the
                          previous newline is ignored */
   printf("ch1: %c, ch2: %c\n", ch1, ch2);

   /* All good so far */

   char ch3;
   scanf("%c", &ch3); /* Doesn't read input due to the same problem */
   printf("ch3: %c\n", ch3);

   return 0;
}

Bien que le 3ème scanf () puisse être corrigé de la même manière en utilisant un espace, le résultat ne sera pas toujours aussi simple que ci-dessus . Un autre problème majeur est que scanf() n'ignorera aucune entrée dans le flux d'entrée s'il ne le fait pas. ne correspond pas au format. Par exemple, si vous saisissez abc pour une int telle que: scanf("%d", &int_var);, alors abc devra être lu et ignoré. Considérer:

#include <stdio.h>

int main(void)
{
    int i;

    while(1) {
        if (scanf("%d", &i) != 1) { /* Input "abc" */
            printf("Invalid input. Try again\n");
        } else {
            break;
        }
    }

    printf("Int read: %d\n", i);
    return 0;
}

Un autre problème courant consiste à mélanger scanf() et fgets(). Considérer:

#include <stdio.h>

int main(void)
{
    int age;
    char name[256];
    printf("Input your age:");
    scanf("%d", &age); /* Input 10 */
    printf("Input your full name [firstname lastname]");
    fgets(name, sizeof name, stdin); /* Doesn't read! */
    return 0;
}

L'appel à fgets() n'attend pas l'entrée car la nouvelle ligne laissée par l'appel précédent de scanf () est lue et fgets () termine la lecture de l'entrée lorsqu'il rencontre une nouvelle ligne.

Il existe de nombreux autres problèmes similaires associés à scanf(). C'est pourquoi il est généralement recommandé de l'éviter.

Alors, quelle est l'alternative? Utilisez fgets() function à la place de la manière suivante pour lire un seul caractère:

#include <stdio.h>

int main(void)
{
    char line[256];
    char ch;

    if (fgets(line, sizeof line, stdin) == NULL) {
        printf("Input error.\n");
        exit(1);
    }

    ch = line[0];
    printf("Character read: %c\n", ch);
    return 0;
}

Un détail à prendre en compte lors de l'utilisation de fgets() lit le caractère de nouvelle ligne s'il y a suffisamment de place dans le tampon inutile. Si ce n'est pas souhaitable, vous pouvez le supprimer:

char line[256];

if (fgets(line, sizeof line, stdin) == NULL) {
    printf("Input error.\n");
    exit(1);
}

line[strcpsn(line, "\n")] = 0; /* removes the trailing newline, if present */
12
P.P.

Voici une chose similaire que je voudrais partager,

pendant que vous travaillez sur Visual Studio, vous risquez d’obtenir une erreur du type: 'scanf': une fonction ou une variable peut présenter un risque. Pensez à utiliser scanf_s à la place. Pour désactiver la désapprobation, utilisez _CRT_SECURE_NO_WARNINGS

Pour éviter cela, vous devriez l'écrire au format suivant

Un seul caractère peut être lu comme suit:

char c;
scanf_s("%c", &c, 1);

Lorsque plusieurs caractères de chaînes terminées non NULL sont lus, des entiers sont utilisés en tant que spécification de largeur et taille du tampon.

char c[4];
scanf_s("%4c", &c, _countof(c));

Cordialement,

1
Sanberk

ni fgets ni getchar ne résout le problème . la seule solution consiste à conserver un espace avant% c lors de l'utilisation de scanf scanf ("% c", ch); // ne fonctionnera que

Dans la suite fgets aussi ne fonctionne pas ..

char line[256];
char ch;
int i;

printf("Enter a num : ");
scanf("%d",&i);
printf("Enter a char : ");

if (fgets(line, sizeof line, stdin) == NULL) {
    printf("Input error.\n");
    exit(1);
}

ch = line[0];
printf("Character read: %c\n", ch);
0
CoderTag

Cela fonctionne pour moi l'essayer

int main(){
char c;
scanf(" %c",&c);
printf("%c",c);
return 0;
}
0
Praveen samuel

Avant le scan, mettez fflush(stdin); pour effacer le tampon. 

0
SYLVIO CAVALCANTI

essayez d'utiliser getchar (); au lieu

syntaxe:

void main() {
    char ch;
    ch = getchar();
}
0
kesarling

Vous devez utiliser une variable valide. ch n'est pas une variable valide pour ce programme. Utilisez char Aaa

char aaa;
scanf("%c",&Aaa);

Testé et ça marche.

0
AL Maruf

Fournit un espace avant le spécificateur de conversion% c afin que le compilateur ignore les espaces. Le programme peut être écrit comme ci-dessous:

#include <stdio.h>
#include <stdlib.h>
int main()
{
    char ch;
    printf("Enter one char");
    scanf(" %c", &ch); /*Space is given before %c*/
    printf("%c\n",ch);
return 0;
}
0
Shahid Nawaz