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

时间:2015-05-06 00:50:48

标签: c user-input scanf format-specifiers

我想在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;
}

5 个答案:

答案 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的最大大小。这里,[]是扫描集字符。

  1. ^\n代表输入,直到没有换行符为止。

  2. 然后,使用此%*c读取换行符,在这里使用的*表示该换行符已被丢弃。

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

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

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

scanf(“%[^ \ n]%* c”,&sen []); 将帮助您获得整个句子,直到没有遇到下一行” \ n” 或在“%[^ \ n]” 的帮助下按下Enter键,其中 [] 是扫描集字符。 ”%* c” 将读取换行符,星号” *” 用于表示下一行字符已被丢弃。

答案 4 :(得分:0)

%[^\n]%*c

这将把直到换行符的所有内容读入您传递的字符串中,然后将消耗单个字符(换行符)而不将其分配给任何字符(“ *”为“赋值抑制”)。

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

在格式指令(%[^\n])中添加空格字符的问题是空格将匹配任何空白。因此,它将从上一个输入的末尾开始使用换行符,但还将吞噬其他任何空格(包括多个换行符)。