"scanf( "%*[^n]%*c" )"是什么意思?



我想在 C 中创建一个循环,当程序请求整数并且用户键入非数字字符时,程序会再次请求一个整数。

我刚刚找到了下面的代码。 但我不明白这意味着什么scanf("%*[^n]%*c").^n是什么意思?^nc之前的*是什么意思?

/*
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 nnn");
printf("Enter your 4 notes between 0 and 100 to calculate your course gradenn");
// 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 nn" , meanValue, grade);
return 0;
}

scanf("%*[^n]%*c")的细分:

  • %*[^n]扫描所有内容直到n,但不扫描n。星号(*)告诉它丢弃扫描的任何内容。
  • %*c扫描单个字符,在这种情况下,这将是%*[^n]留下的n。星号指示scanf丢弃扫描的字符。

%[%c都是格式说明符。你可以在这里看到他们做了什么。两个说明符中的星号都告诉scanf,不要存储这些格式说明符读取的数据。

正如下面@chux评论的那样,它将清除stdin(标准输入流)的单行,直到并包括换行符。在您的情况下,输入无效的行将从stdin中清除。


最好使用

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

清除stdin。这是因为,在前一种情况下(单scanf),当要扫描的第一个字符是n字符并且将跳过scanf的其余格式字符串时,%*[^n]将失败,这意味着%*c将不起作用,因此,来自输入的n仍将在输入流中。在这种情况下,这不会发生,因为即使第一个scanf失败,第二个也会执行,因为它们是单独的scanf语句。

您可以使用scanf(“%s”, s)将字符串作为 C 中的输入。但是,它只接受字符串,直到找到第一个空格。

为了将行作为输入,您可以使用scanf("%[^n]%*c", s);其中s定义为char s[MAX_LEN]其中MAX_LENs的最大大小。在这里,[]是扫描字符。^n代表在没有遇到换行符之前接受输入。然后,使用此%*c,它读取换行符,在这里,使用的*表示此换行符被丢弃。

假设charsen[max_length],其中最大长度是sen[]的最大大小。

这个scanf("%[^]%*c",&sen[]);将帮助您获取整个句子,直到没有遇到下一行""或按回车键,这是在"%[^]">的帮助下完成的,这里[ ]是扫描集字符。 "%*c"将读取换行符,星号"*">用于表示下一行字符被丢弃

%[^n]%*c

它会将换行符的所有内容读入您传入的字符串中,然后将使用单个字符(换行符)而不将其分配给任何内容("*"是"赋值抑制")。

否则,换行符将保留在输入流中,等待立即终止后续的%[^n]格式指令。

在格式指令(%[^n])中添加空格字符的问题是空格将匹配任何空格。因此,它将吃掉上一个输入末尾的换行符,但它也会吃掉任何其他空格(包括多个换行符)。

本质上,这是使用 scanf 的两次读取。第一部分 "%[^]" 表示"读取所有不是换行符的内容",这被分配给 字符缓冲区 str。

第二部分"%*c"表示"读取下一个字符但不保存它 任何地方';这摆脱了我们在 第一部分。

https://www.sololearn.com/Discuss/2249429/what-s-the-use-of-scanf-n-c-in-c-programming

为了将一行作为输入,您可以使用scanf("%[^n]%*c", s);其中定义为char s[MAX_LEN]其中 是 的最大大小。此处,[]是扫描集字符。^n代表在没有遇到换行符之前接受输入。然后,使用此 %*c,它读取换行符,在这里,使用的 * 表示丢弃此换行符。

最新更新