我有一个疑问,例如我是否有这样的输入:
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? 谢谢......
答案 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'
。