fgets和sscanf in c

发布于 2025-02-02 03:23:43 字数 804 浏览 3 评论 0原文

我有一个文件正在尝试提取整数和字符。

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: %d\n", ROW, COL);
    }
    
    else
    {
        sscanf(line, "%d %d %c\n", &xPos, &yPos, &zType);
        printf("xPos: %d, yPos: %d, zType: %c\n", 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

我希望它获得前两个整数并将其存储在行和col中,然后将其余的线分别存储在XPO,YPOS和ZTYPE中。

I have a file I'm trying to extract the integers and characters out of.

10 20
0 0 #
1 0 |
2 0 |
3 0 |
3 1 -
3 2 -
3 3 -
3 4 >

My current code is:

while(fgets(line, sizeof(line), snakeFile) != NULL)
{
    if(sscanf(line, "%d %d", &ROW, &COL) == 2)
    {
        printf("ROW: %d, COL: %d\n", ROW, COL);
    }
    
    else
    {
        sscanf(line, "%d %d %c\n", &xPos, &yPos, &zType);
        printf("xPos: %d, yPos: %d, zType: %c\n", xPos, yPos, zType);
    }

}

However I get as the output:

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

I would like it to get the first two integers and store it in ROW and COL and then the rest of the lines underneath it stored in xPos, yPos and zType respectively.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

残花月 2025-02-09 03:23:43

您似乎正在使用条件

if(sscanf(line, "%d %d", &ROW, &COL) == 2)

来确定您当前是否正在处理第一行。但是,这种情况无法确定这一点,因为所有线路,而不仅仅是第一个条件都将是正确的。功能scanf将成功匹配2个数字,然后忽略该行的其余部分。

您可以做的一件事是将该行更改为

if ( sscanf(line, "%d %d %c\n", &xPos, &yPos, &zType) == 3 )

else> else block,并交换的内容。这应该起作用,因为除第一条线以外的所有线路都将是正确的。

但是,一个更简单的解决方案是不要尝试处理循环内的第一行,而是要在循环外处理该行:

if( sscanf( line, "%d %d", &ROW, &COL) != 2 )
{
    fprintf( stderr, "Conversion failure!\n" );
    exit( EXIT_FAILURE );    
}

printf("ROW: %d, COL: %d\n", 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: %c\n",
             xPos, yPos, zType
        );
    }
    else
    {
        fprintf(
            stderr,
            "Warning: Conversion failure occurred on one line! This could\n"
            "be harmless, for example it could be caused by an empty\n"
            "line at the end of the file.\n"
        );
    }
}

请注意,您可能必须添加#include< stdlib.h>能够调用函数退出

You appear to be using the condition

if(sscanf(line, "%d %d", &ROW, &COL) == 2)

to determine whether you are currently processing the first line or not. However, this condition is unable to determine this, because that condition will be true with all lines, not just the first one. The function scanf will successfully match 2 numbers and will then ignore the rest of the line.

One thing you could do would be to change that line to

if ( sscanf(line, "%d %d %c\n", &xPos, &yPos, &zType) == 3 )

and to swap the contents of the if and the else block. This should work, because this condition will be true for all lines except the first one.

However, a simpler solution would be to not attempt to handle the first line inside the loop, but to instead handle that line outside the loop:

if( sscanf( line, "%d %d", &ROW, &COL) != 2 )
{
    fprintf( stderr, "Conversion failure!\n" );
    exit( EXIT_FAILURE );    
}

printf("ROW: %d, COL: %d\n", 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: %c\n",
             xPos, yPos, zType
        );
    }
    else
    {
        fprintf(
            stderr,
            "Warning: Conversion failure occurred on one line! This could\n"
            "be harmless, for example it could be caused by an empty\n"
            "line at the end of the file.\n"
        );
    }
}

Note that you may have to add #include <stdlib.h> to be able to call the function exit.

心凉 2025-02-09 03:23:43

sscanf(行,“%d%d”,&amp; row,&amp; 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] == '\0') {
  printf("ROW: %d, COL: %d\n", ROW, COL);
} else {
  int n = 0;
  sscanf(line, "%d %d %c %n", &xPos, &yPos, &zType, &n);
  if (n > 0 && line[n] == '\0') {
    printf("xPos: %d, yPos: %d, zType: %c\n", xPos, yPos, zType);
  } else {
    printf("No match\n");
  }
}

如果扫描包含所需的后缀,这也很好。

考虑输入:

< 0 0 # >
< 1 0 | >
< 2 0 | >

然后使用”扫描&lt;%d%d%d%c&gt;%n”

sscanf(line, "%d %d", &ROW, &COL) == 2 matches every line of OP's sample as each line begins with 2 numbers.


A real neat way of testing if the entire line was scanned uses " %n" to store the offset of the scan.

This works well even if the last line of the file lacked a '\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] == '\0') {
  printf("ROW: %d, COL: %d\n", ROW, COL);
} else {
  int n = 0;
  sscanf(line, "%d %d %c %n", &xPos, &yPos, &zType, &n);
  if (n > 0 && line[n] == '\0') {
    printf("xPos: %d, yPos: %d, zType: %c\n", xPos, yPos, zType);
  } else {
    printf("No match\n");
  }
}

This also works well if the scan included a required suffix.

Consider input like:

< 0 0 # >
< 1 0 | >
< 2 0 | >

Then scan with " < %d %d %c > %n"

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文