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.
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);
où s
est défini comme char s[MAX_LEN]
où 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é.