我有一个文件,我试图提取整数和字符。
10 20
0 0 #
1 0 |
2 0 |
3 0 |
3 1 -
3 2 -
3 3 -
3 4 >
我当前的代码是:
while(fgets(line, sizeof(line), snakeFile) != NULL)
{
if(sscanf(line, "%d %d", &ROW, &COL) == 2)
{
printf("ROW: %d, COL: %dn", ROW, COL);
}
else
{
sscanf(line, "%d %d %cn", &xPos, &yPos, &zType);
printf("xPos: %d, yPos: %d, zType: %cn", xPos, yPos, zType);
}
}
但是我得到的输出是:
ROW: 10, COL: 20
ROW: 0, COL: 0
ROW: 1, COL: 0
ROW: 2, COL: 0
ROW: 3, COL: 0
ROW: 3, COL: 1
ROW: 3, COL: 2
ROW: 3, COL: 3
ROW: 3, COL: 4
我希望它获得前两个整数并将其存储在ROW和COL中,然后将其下面的其余行分别存储在xPos, yPos和zType中。
您似乎正在使用条件
if(sscanf(line, "%d %d", &ROW, &COL) == 2)
来确定当前是否正在处理第一行。然而,这个条件无法确定这一点,因为该条件对所有行都为真,而不仅仅是第一行。函数scanf
将成功匹配2个数字,然后忽略该行的其余部分。
你可以做的一件事是将这行改为
if ( sscanf(line, "%d %d %cn", &xPos, &yPos, &zType) == 3 )
和交换if
和else
块的内容。这应该可以工作,因为除了第一行之外,该条件对所有行都为真。
if( sscanf( line, "%d %d", &ROW, &COL) != 2 )
{
fprintf( stderr, "Conversion failure!n" );
exit( EXIT_FAILURE );
}
printf("ROW: %d, COL: %dn", ROW, COL);
while ( fgets(line, sizeof(line), snakeFile) != NULL )
{
if ( sscanf(line, "%d %d %c", &xPos, &yPos, &zType) == 3 )
{
printf(
"xPos: %d, yPos: %d, zType: %cn",
xPos, yPos, zType
);
}
else
{
fprintf(
stderr,
"Warning: Conversion failure occurred on one line! This couldn"
"be harmless, for example it could be caused by an emptyn"
"line at the end of the file.n"
);
}
}
注意,您可能必须添加#include <stdlib.h>
才能调用函数exit
。
sscanf(line, "%d %d", &ROW, &COL) == 2
匹配OP样本的每行,因为每行以2个数字开头。
一种真正简洁的测试整行是否被扫描的方法是使用" %n"
来存储扫描的偏移量。
即使文件的最后一行缺少'n'
,也可以正常工作。
// if(sscanf(line, "%d %d", &ROW, &COL) == 2)
int n = 0;
sscanf(line, "%d %d %n", &ROW, &COL, &n);
if (n > 0 && line[n] == ' ') {
printf("ROW: %d, COL: %dn", ROW, COL);
} else {
int n = 0;
sscanf(line, "%d %d %c %n", &xPos, &yPos, &zType, &n);
if (n > 0 && line[n] == ' ') {
printf("xPos: %d, yPos: %d, zType: %cn", xPos, yPos, zType);
} else {
printf("No matchn");
}
}
如果扫描包含所需的后缀,这也可以很好地工作。
考虑如下输入:
< 0 0 # >
< 1 0 | >
< 2 0 | >
然后用" < %d %d %c > %n"
扫描