0
votes

Pourquoi les deux invites dans ce programme ont-elles été utilisées pour recevoir une émission d'entrée sur la même ligne?

J'ai un problème lors de la saisie de l'utilisateur. J'ai utilisé la fonction scanf pour obtenir l'entrée de l'utilisateur, que je pense est la cause du problème.

Je veux que les deux invites soient sur des lignes distinctes.

Le code suivant est un exemple simple du problème: xxx

le résultat comme texte: xxx

une image:

Pourquoi les deux invites sont-elles montrées sur la même ligne?


0 commentaires

3 Réponses :


3
votes

Comme les autres commentaires conseillent, vous ferez mieux d'utiliser % 19 [^ \ n] code>. Cependant, cela fera toujours votre problème. Cela devrait fonctionner:

Program output
 clang-7 -pthread -lm -o main main.c
 ./main
1- Insert a new student.
2- Delete a student.
3- Show all students.
4- Exit.

Choose: 1
Enter your name: jimm
Enter your age: 12
Name: jimm, Age: 12


0 commentaires

1
votes

Je vous suggère de changer ceci: xxx

à ceci: xxx

pour ces raisons:

  • La taille de la mémoire tampon que vous spécifiez sur scanf n'inclut pas le terminateur final nul (contrairement à fgets ).

  • le précédent scanf laissé une nouvelle ligne dans la mémoire tampon d'entrée et les spécificateurs de format % [] et % c ne pas filtrer automatiquement (contrairement à % d et autres spécificateurs). Ajouter l'espace indique scanf pour le filtrer.

  • La finale s ne fait pas partie du format % [] mais est une erreur fréquente de codeurs qui ont utilisé % s .

    note aussi, que scanf avec % [] n'est pas équivalent à fgets () , qui lit toute nouvelle ligne finale et place dans le tampon fourni.


2 commentaires

En ce qui concerne fgets il fait le même problème, comment l'utiliser sans causer ce problème?


Je n'ai pas suggéré d'utiliser fgets mais la réponse consiste à ne pas mélanger vos méthodes d'entrée. Si vous utilisez fgets , utilisez-le pour chaque entrée, puis appliquez sscanf à la chaîne d'entrée pour extraire ses données. Il est en fait plus facile de le faire, de récupérer à partir d'une entrée non valide (telle qu'une des données alphabétiques saisies pour un numéro).



1
votes

C'est le code qui devrait faire l'affaire. Veuillez consulter les commentaires contenus dans le code:

#include <stdio.h>

int main(void) {

  int age = 0;
  int index;
  char name[20];
  int ignore; // Not char as EOF is -1

  // Keep repeating the menu until a valid input
  do {
    printf("1- Insert a new student.\n");
    printf("2- Delete a student.\n");
    printf("3- Show all students.\n");
    printf("4- Exit.\n\nChoose: ");
  while (scanf("%d", &index) != 1 || index < 1 || index > 4); // Check for a valid index

  if (index == 1) { // Choice 1 chosen (maybe switch would be better?

    printf("Enter your name: ");
    fflush(stdout); // So it goes to the terminal
    scanf(" %19[^\n]", name);

    while (1) {
      printf("Enter your age: ");
      fflush(stdout); // So it goes to the terminal
      if (scanf(" %d", &age) == 1 && age > 0) { // I.e. valid age has been read
        break; // We are done with this loop
      }
      // Consume up to end of line
      do {
        ignore == fgetc(stdin);
        if (ignore == EOF) { // Nothing more to be read - error as no age entered
          return -1;
        }
      } while (ignore != '\n');
    }
    printf("Name: %s, Age: %d\n", name, age);
    // Do not need fflush as printf contains \n at the end
    return 0;
  }
    // ... for the other options
}


0 commentaires