【问题标题】:Reading Stdin in chunks... (possibly with scanf?)分块读取标准输入......(可能使用scanf?)
【发布时间】:2013-06-09 03:03:35
【问题描述】:

我有一个 linux 盒子。

在这个linux机器上,有一个程序。

在这个程序中,我有一个这样的循环:

int num=*"what num needs to be"*;
char proc[num];

int result;
while (1) {
result=scanf("%[^'&']%s",proc);
printf("And proc is: %s\n",proc);
printf("Result counter was: %i\n",result)
if (result == 0) break;
}

scanf("%[^'&'],%s",proc)
printf("post lop result is: %s", proc);

您可能已经猜到了,stdin 包含我需要用 '&' 字符描述的数据。

我希望有人比我猜到的更熟练,输出看起来像:

And proc is: *first delineated section*
Result counter was: 1
And proc is: *first delineated section*
Result counter was: 0
post loop result is: *first delineated section*

我认为 scanf 应该消耗它已经读取的 stdin 部分。为什么不这样做?

另外,仅供参考:这是在一个非常便宜、速度慢的服务器上运行的。成交量可能会或可能不会变得非常轻微。因此效率是一个加分项,我愿意,但是有人可能会建议我这样做......

谢谢!

【问题讨论】:

    标签: c linux cgi scanf


    【解决方案1】:

    问题在于,在第二次迭代中,scanf 无法读取您给它的格式(从标准输入读取的行不匹配)并且不会修改 proc.这也是它返回 0 的原因:它已成功读取(并因此修改)0 个字段。

    【讨论】:

      【解决方案2】:

      扫描集不需要两个单引号——如果你想在单引号上打断,一个就足够了,但我怀疑你只想在& 上停下来,下面的代码也假设了这一点。阅读完第一个& 后,您需要一些代码来阅读&。在使用它返回的数据之前,您需要检查scanf() 的结果。

      因此:

      int num = 100;
      char proc[num];
      
      int result;
      while ((result = scanf("%99[^&]", proc)) == 1)
      {
          printf("And proc is: <<%s>>\n", proc);
          printf("Result counter was: %i\n", result);
          int c;
          while ((c = getchar()) != EOF && c != '&')
              ;
      }
      

      您还需要确定换行符是否也标记字段的结尾...如果是,则:

      int num = 100;
      char proc[num];
      
      int result;
      while ((result = scanf("%99[^&\n]", proc)) == 1)
      {
          printf("And proc is: <<%s>>\n", proc);
          printf("Result counter was: %i\n", result);
          int c;
          while ((c = getchar()) != EOF)
          {
              if (c != '&' && c != '\n')
              {
                  ungetc(c, stdin);
                  break;
              }
          }
      }
      

      注意使用%99[...] 来防止缓冲区溢出。尖括号&lt;&lt;%s&gt;&gt; 只是标记字符串的开始和结束;例如,它们使尾随空格和制表符可见。

      该代码假定您有一个 C99 编译器,该编译器允许在代码块中途声明变量。如果没有,请将int c; 移至循环顶部

      【讨论】:

      • scanf() 的格式指定它应该分配给两个参数,但只传递一个。这是从提问者的原始代码传播的错误。
      猜你喜欢
      • 2018-08-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-31
      • 2018-05-11
      • 2013-02-12
      • 1970-01-01
      相关资源
      最近更新 更多