web-dev-qa-db-fra.com

Que signifie `scanf ("% * [^\n]% * c ")`?

Je veux créer une boucle en C qui, lorsque le programme demande un entier et que l'utilisateur tape un caractère non numérique, le programme demande à nouveau un entier.

Je viens de trouver le code ci-dessous. mais je ne comprends pas ce que cela signifie scanf("%*[^\n]%*c"). Que signifie ^\n? Que signifient les * avant ^\n et c?

/*

 This program calculate the mean score of an user 4 individual scores,
 and outputs the mean and a final grade
 Input: score1, score2,score2, score3
 Output: Mean, FinalGrade

*/
#include <stdio.h>
//#include <stdlib.h>

int main(void){
  int userScore = 0; //Stores the scores that the user inputs
  float meanValue = 0.0f; //Stores the user mean of all the notes
  char testChar = 'f'; //Used to avoid that the code crashes
  char grade = 'E'; //Stores the final 
  int i = 0; //Auxiliar used in the for statement

  printf("\nWelcome to the program \n Tell me if Im clever enough! \n Designed for humans \n\n\n");
  printf("Enter your 4 notes between 0 and 100 to calculate your course grade\n\n");

  // Asks the 4 notes. 
  for ( ; i<=3 ; i++ ){
    printf("Please, enter your score number %d: ", i+1);

    //If the note is not valid, ask for it again

    //This is tests if the user input is a valid integer.
    if ( ( scanf("%d%c", &userScore, &testChar)!=2 || testChar!='\n')){
      i-=1;
      scanf("%*[^\n]%*c");

    }else{ //Enter here if the user input is an integer
      if ( userScore>=0 && userScore<=100 ){
    //Add the value to the mean
    meanValue += userScore;
      }else{ //Enter here if the user input a non valid integer
    i-=1;
    //scanf("%*[^\n]%*c");
      }    
    }
  }

  //Calculates the mean value of the 4 scores
  meanValue = meanValue/4;

  // Select your final grade according to the final mean
  if (meanValue>= 90 && meanValue <=100){
    grade = 'A';
  } else if(meanValue>= 80 && meanValue <90){
    grade = 'B';
  } else if (meanValue>= 70 && meanValue <80){
    grade = 'C';
  } else if(meanValue>= 60 && meanValue <70){
    grade = 'D';
  }
  printf("Your final score is: %2.2f --> %c \n\n" , meanValue, grade);

  return 0;
}

Ventilation de scanf("%*[^\n]%*c"):

  • %*[^\n] scanne tout jusqu'à un \n, mais n'analyse pas dans le \n. L'astérisque (*) lui indique de supprimer tout ce qui a été numérisé.
  • %*c scanne un seul caractère, qui sera le \n laissé par %*[^\n] dans ce cas. L'astérisque indique à scanf de supprimer le caractère balayé.

%[ et %c sont des spécificateurs de format. Vous pouvez voir ce qu'ils font ici . Les astérisques dans les deux spécificateurs indiquent à scanf de ne pas stocker les données lues par ces spécificateurs de format.

Comme @chux commenté ci-dessous , il effacera une seule ligne de la stdin (flux d'entrée standard) jusqu'au caractère de nouvelle ligne inclus. Dans votre cas, la ligne avec une entrée non valide est effacée de la variable stdin.


Il vaut mieux utiliser

scanf("%*[^\n]");
scanf("%*c");

pour effacer la stdin. En effet, dans le premier cas (unique scanf), %*[^\n] échouera lorsque le premier caractère à analyser est le caractère \n et le reste de la chaîne de formatage de la scanf sera ignoré, ce qui signifie que le %*c ne fonctionnera pas et donc , le \n de l’entrée sera toujours dans le flux d’entrée. Dans ce cas, cela ne se produira pas car même lorsque la première scanf échoue, la seconde s'exécutera car il s'agit d'instructions scanf distinctes.

15
Spikatrix

Vous pouvez prendre une chaîne comme entrée en C en utilisant scanf(“%s”, s). Mais, il accepte uniquement les chaînes jusqu'à ce qu'il trouve le premier espace.

Afin de prendre une ligne en entrée, vous pouvez utiliser scanf("%[^\n]%*c", s);s est défini comme char s[MAX_LEN]MAX_LEN est la taille maximale de s. Ici, [] est le caractère d'analyse. ^\n signifie que vous saisissez une entrée jusqu'à ce qu'une nouvelle ligne ne soit plus rencontrée. Ensuite, avec ce %*c, il lit le caractère de nouvelle ligne et ici, le * utilisé indique que ce caractère de nouvelle ligne est ignoré.

0
Gagan Agarwal