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

Gus*_*os 7 c user-input scanf format-specifiers

我想在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 \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;
}
Run Code Online (Sandbox Code Playgroud)

Spi*_*rix 20

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

  • %*[^\n]扫描一切,直到a \n,但不扫描\n.星号(*)告诉它放弃扫描的内容.
  • %*c扫描单个字符,在这种情况下将是\n剩下的字符%*[^\n].星号指示scanf丢弃扫描的字符.

这两个%[%c格式说明.你可以看到他们在这里什么.两个说明符中的星号都表示scanf不存储这些格式说明符读取的数据.

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


最好使用

scanf("%*[^\n]");
scanf("%*c");
Run Code Online (Sandbox Code Playgroud)

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


小智 5

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

为了将一行作为输入,您可以使用scanf("%[^\n]%*c", s);where 定义为char s[MAX_LEN]whereMAX_LEN是 s 的最大大小。这里,[]是扫描集字符。

  1. ^\n 代表接受输入直到没有遇到换行符。

  2. 然后,用 this %*c,它读取换行符,这里, used*表示这个换行符被丢弃。

还要注意的是:输入字符和字符串后,按上述语句输入语句将不起作用。这是因为,在每一行的末尾,存在一个换行符\n。因此,语句:scanf("%[^\n]%*c", s);将不起作用,因为最后一条语句将从前一行读取换行符。这可以通过多种方式处理,其中之一是:scanf("\n");在最后一条语句之前。

  • 答案是黑客地球中对其中一个问题的逐字描述 (2认同)