Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么是scanf();跳过第一行?_C_String_Scanf - Fatal编程技术网

为什么是scanf();跳过第一行?

为什么是scanf();跳过第一行?,c,string,scanf,C,String,Scanf,所以在scanf之后,printf()跳过第一行 我读过一些问题,它们告诉我,“%[^\n]”必须是“%[^\n]”才能跳过换行符 我已经尝试了这两种方法,但它仍然打印相同的结果,现在我不知道为什么它不起作用 Example input Enter number of Materi: 4 Materia 1 name : a Materia 2 name : b materia 3 name : c materia 4 name : d Output: Materia - 1 : R╒fu M

所以在scanf之后,
printf()跳过第一行
我读过一些问题,它们告诉我,
“%[^\n]”
必须是
“%[^\n]”
才能跳过换行符
我已经尝试了这两种方法,但它仍然打印相同的结果,现在我不知道为什么它不起作用

Example input
Enter number of Materi: 4
Materia 1 name : a
Materia 2 name : b
materia 3 name : c
materia 4 name : d

Output:
Materia - 1 : R╒fu
Materia - 2 : a
Materia - 3 : b
Materia - 4 : c
#包括
#包括
int main(int argc,const char*argv[]{
int i;
INTV;
printf(“输入材料编号:”);
scanf(“%d”和“&V”);fflush(stdin);
//插入材料
炭材料[V][50];
对于(i=0;i
使用
fgets
而不是
scanf
。换行符作为字符被后续的
scanf
使用。这就是您面临此问题的原因。

使用
fgets
而不是
scanf
。换行符作为字符被后续的
scanf
使用。这就是您面临此问题的原因。

在以下行中:

scanf("%[^\n]", &materia[i][50]); 
您将输入的字符串存储在
materiala[i][50]
的地址中,有效地将其存储在数组的边界之外

这里发生了一些有趣的事情,2D数组存储是连续的,就像它是一个一维向量一样,发生的事情是将第一个字符串存储在数组第二行的开头,第二个字符串存储在第三行,依此类推,将第一个字符串留空。这就是程序产生的输出的合理性

使用以下命令更正您的代码:

#include<stdlib.h>

//...

if(scanf(" %49[^\n]", materia[i] != 1) {
   puts("Read error");
   return EXIT_FAILURE;       
}
#包括
//...
如果(scanf(“%49[^\n]”,material[i]!=1){
puts(“读取错误”);
返回退出失败;
}
49个字符+nul终止符为避免溢出,说明符开头的空格可避免消耗
stdin
缓冲区中的空白字符。始终验证
scanf
返回以避免读取错误

其他一些问题:

  • fflush(stdin)
    应根据需要删除

  • 如果消耗了足够的内存,可变长度数组可能会导致堆栈溢出,在这种情况下不太可能,但要记住这一点

行中:

scanf("%[^\n]", &materia[i][50]); 
您将输入的字符串存储在
materiala[i][50]
的地址中,有效地将其存储在数组的边界之外

这里发生了一些有趣的事情,2D数组存储是连续的,就像它是一个一维向量一样,发生的事情是将第一个字符串存储在数组第二行的开头,第二个字符串存储在第三行的开头,依此类推,将第一个字符串保留为空。这就是程序生成的输出的合理性

使用以下命令更正您的代码:

#include<stdlib.h>

//...

if(scanf(" %49[^\n]", materia[i] != 1) {
   puts("Read error");
   return EXIT_FAILURE;       
}
#包括
//...
如果(scanf(“%49[^\n]”,material[i]!=1){
puts(“读取错误”);
返回退出失败;
}
49个字符+nul终止符为避免溢出,说明符开头的空格可避免消耗
stdin
缓冲区中的空白字符。始终验证
scanf
返回以避免读取错误

其他一些问题:

  • fflush(stdin)
    应根据需要删除

  • 如果消耗了足够的内存,可变长度数组可能会导致堆栈溢出,在这种情况下不太可能,但要记住这一点


    • 程序中有几个错误

      • 传递给
        scanf
        的数组错误

      • fflush(stdin)
        是非标准的,尽管Windows支持它,但它不可移植。但是您不使用Windows,因为它不支持VLA
        char material[V][50];

      • scanf
        format
        “%[^\n]”
        将停止的换行已经是输入缓冲区中的下一个字符

      • 未检查来自
        scanf
        的返回值。它是成功扫描的项目数

      • 由于输入字符串长度不受限制,因此可能会出现缓冲区溢出

      以下是调整后的代码:

      #include<stdio.h>
      
      int main(int argc, const char *argv[]){
      
          int i;
          int V;
      
          printf("Enter number of Materi: ");
          if(scanf("%d", &V) != 1) {
              /* add some error message */
              return 1;
          }
          // fflush(stdin);               // removed
      
          //Insert materia
          char materia[V][50];
          for(i = 0; i < V; i++){
              printf("Materia %d name : ", i+1);
              // add a space to filter the newline
              // correct the array passed
              // and restrict the length to prevent buffer overflow
              if(scanf(" %49[^\n]", materia[i]) != 1) {
                  /* add some error message */
                  return 1;
              }
              // fflush(stdin);           // removed
          }
      
          for(i = 0; i < V; i++){
              printf("Materia - %d: %s\n", i+1, materia[i]);
          }
      
          return 0;
      }
      
      #包括
      int main(int argc,const char*argv[]{
      int i;
      INTV;
      printf(“输入材料编号:”);
      如果(扫描频率(“%d”,&V)!=1){
      /*添加一些错误消息*/
      返回1;
      }
      //fflush(stdin);//已删除
      //插入材料
      炭材料[V][50];
      对于(i=0;i
      关于换行符。格式规范
      %d
      %s
      %f
      会自动过滤掉前导空格,但
      %c
      %[]
      %n
      不会。
      scanf
      函数在无法转换的第一个字符处停止,该字符留在输入缓冲区中。
      %[^\n]
      告诉它在第一个换行符处停止。但是已经有一个换行符,从第一个
      %d
      scanf开始,它需要被删除,也需要在后续的迭代中删除,添加空格就可以了。之后尝试删除它是笨拙的,不能保证有效


      每次使用时都必须检查
      scanf
      中的返回值。它是成功扫描的项目数。在这里,两种用法中都应该是
      1
      。因此,如果一条语句中有两个项目,则其返回值必须是
      2

      程序中存在多个错误

      • T