从stdin读取的变量输入

时间:2014-03-17 23:25:42

标签: c input stdin

我有一个疑问,例如我是否有这样的输入:

5 4
1 2 3 4 5
2 3 4
2 3
1 2 3

第一个数字表示不同的玩具"每个孩子都要归因于第二个数字,这个数字是4,结果是代表每个孩子的行数和他们想要的玩具......

我如何在ansi C中读取这样的输入? 使用strtok?还是有其他更简单的方法吗?

我可以用这样的东西做到这一点

char line [250];
char * tok;
char *ptr = line;


while((scanf("%s",line)!= EOF){

    while ((tok = strtok(ptr, " ")) != NULL)
    {
        pseudo part
        //convert to int
        //add to array

    }

}

但是有没有更简单的方法来做这个输入而不使用tok? 谢谢......

2 个答案:

答案 0 :(得分:1)

您可以使用fgets来读取一行,而不是scanf。 scanf只读到第一个空格。 (最好使用fgets,因为它比gets更安全

像这样:

ptr = fgets(line,sizeof(line),stdin);

如果在第一次调用后将ptr设置为NULL,则strtok将起作用。 无论如何,最好添加更多的空格,例如:" \r\n\t"

//assume ptr = line had been set by fgets...
char* tok;
do{
   const char* whitespaces = " \r\n\t";
   tok = strtok(ptr, whitespaces);
   ptr = NULL;//till next fgets
   if(tok){
      //got more number  
   }
}while(tok);

答案 1 :(得分:1)

推荐经典fgets()/sscanf()组合。

一次读一行。良好的错误检查可用。使用"%n"知道下一次玩具的下一次扫描的开始位置。

char buffer[250];
if (fgets(buffer, sizeof buffer, stdin) == NULL)
  HandleEOF();
int toys, kids;
int cnt = sscanf(buffer, "%d%d", &toys, &kids);
if (cnt != 2 || toys <= 0 || kids <= 0)
  Handle_BadToysKids(cnt);
int kid_wants[kids][toys] = { 0 };

for (int k = 0; k < kids; k++) {
  if (fgets(buffer, sizeof buffer, stdin) == NULL)
    HandleEOF();
  char *p = buffer;
  int want;
  int n;
  while ((cnt = sscanf(p, "%d %n", &want, &n)) == 1) {
    if (want <= 0 || want > toys)
      Handle_BadWant(want);
    kid_wants[k][want - 1] = 1;
    p += n;
  }
}

改进:
使用size_t toys, kids"%zu" 使用sentinel检查一行上的额外垃圾:
int ch; int cnt = sscanf(buffer, "%d%d %c", &toys, &kids, &ch);
*p循环结束时检查while - 它应为'\0'