【问题标题】:What does `scanf("%*[^\n]%*c")` mean?`scanf("%*[^\n]%*c")` 是什么意思?
【发布时间】:2015-07-15 22:29:10
【问题描述】:

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

【问题讨论】:

    标签: c user-input scanf format-specifiers


    【解决方案1】:

    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] 将失败,并且将跳过 scanf 的其余格式字符串,这意味着%*c 将不起作用,因此来自输入的\n 仍将在输入流中。在这种情况下,这不会发生,因为即使第一个 scanf 失败,第二个也会执行,因为它们是单独的 scanf 语句。

    【讨论】:

    • 详细信息:当stdin 中有多行输入时,这肯定不会“清除stdin”,但会消耗输入直到并包括下一个行尾。通常对于基本应用程序来说已经足够了。
    【解决方案2】:

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

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

    1. ^\n 表示在没有遇到换行之前接受输入。

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

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

    【讨论】:

    • 答案是黑客地球中对其中一个问题的逐字描述
    • @MohammadYasirKP 也是 GFG 和 Hackerrank 中的逐字描述。
    【解决方案3】:

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

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

    【讨论】:

    • 如果一行输入只包含"\n"scanf("%[^\n]%*c", s); 不读取任何内容,并将"\n" 留在stdin 中。出于这个原因,建议不要使用此代码读取一行,并且没有宽度限制,
    【解决方案4】:

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

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

    【讨论】:

      【解决方案5】:

      %[^\n]%*c

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

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

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

      【讨论】:

        【解决方案6】:

        本质上这是使用 scanf 的两次读取。第一部分“%[^\n]” 意思是“阅读所有不是换行符的东西”,这被分配给 字符缓冲区str。

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

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

        【讨论】:

          猜你喜欢
          • 2017-12-29
          • 2017-07-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-04-15
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多