我想在C中创建一个循环,当程序要求一个整数并且用户键入一个非数字字符时,程序再次询问一个整数。
我刚刚找到了以下代码。但我不明白这意味着什么scanf("%*[^\n]%*c")
。 ^\n
是什么意思? *
和^\n
之前的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;
}
答案 0 :(得分:16)
scanf("%*[^\n]%*c")
的细分:
%*[^\n]
扫描所有内容,直到\n
,但不会在\n
中扫描。星号(*
)告诉它放弃扫描的内容。%*c
会扫描一个字符,在这种情况下,\n
会遗留%*[^\n]
个字符。星号指示scanf
丢弃扫描的字符。 %[
和%c
都是格式说明符。你可以看到他们做了什么here。两个说明符中的星号都告诉scanf
,而不是存储这些格式说明符读取的数据。
作为@chux commented below,它将清除stdin
(标准输入流)的一行,直到并包括换行符。在您的情况下,具有无效输入的行将从stdin
清除。
最好使用
scanf("%*[^\n]");
scanf("%*c");
清除stdin
。这是因为,在前一种情况下(单scanf
),当要扫描的第一个字符是%*[^\n]
字符和{{的格式字符串的其余部分时,\n
将失败将跳过1}}这意味着scanf
将不起作用,因此输入中的%*c
仍将在输入流中。在这种情况下,这不会发生,即使第一个\n
失败,第二个将执行,因为它们是单独的scanf
语句。
答案 1 :(得分:1)
您可以使用scanf(“%s”, s)
将字符串作为C中的输入。但是,它只接受字符串,直到找到第一个空格为止。
为了将一行作为输入,您可以使用scanf("%[^\n]%*c", s);
,其中
定义为char s[MAX_LEN]
,其中MAX_LEN
是s的最大大小。这里,[]
是扫描集字符。
^\n
代表输入,直到没有换行符为止。
然后,使用此%*c
读取换行符,在这里使用的*
表示该换行符已被丢弃。
还请注意:
输入字符和字符串后,按上述语句输入句子将不起作用。这是因为在每一行的末尾都有一个新的行字符\n
。因此,语句scanf("%[^\n]%*c", s);
将不起作用,因为最后一条语句将从前一行读取换行符。这可以通过多种方式来处理,其中一种是:最后一条语句之前的scanf("\n");
。
答案 2 :(得分:0)
您可以使用scanf(“%s”, s)
将字符串作为C中的输入。但是,它只接受字符串,直到找到第一个空格为止。
为了将一行作为输入,可以使用scanf("%[^\n]%*c", s);
,其中s
定义为char s[MAX_LEN]
,其中MAX_LEN
是s
的最大大小。这里,[]
是扫描集字符。 ^\n
代表输入,直到没有换行符为止。然后,使用此%*c
读取换行符,在这里使用的*
表示该换行符已被丢弃。
答案 3 :(得分:0)
假设char sen [max_length],其中最大长度是sen []的最大大小。
此 scanf(“%[^ \ n]%* c”,&sen []); 将帮助您获得整个句子,直到没有遇到下一行” \ n” 或在“%[^ \ n]” 的帮助下按下Enter键,其中 [] 是扫描集字符。 ”%* c” 将读取换行符,星号” *” 用于表示下一行字符已被丢弃。
答案 4 :(得分:0)
%[^\n]%*c
这将把直到换行符的所有内容读入您传递的字符串中,然后将消耗单个字符(换行符)而不将其分配给任何字符(“ *”为“赋值抑制”)。
否则,换行符留在输入流中,等待立即终止后续的%[^\n]
格式指令。
在格式指令(%[^\n]
)中添加空格字符的问题是空格将匹配任何空白。因此,它将从上一个输入的末尾开始使用换行符,但还将吞噬其他任何空格(包括多个换行符)。