【问题标题】:reading lines using fscanf使用 fscanf 读取行
【发布时间】:2013-08-07 08:37:16
【问题描述】:

嗨,我有一个文件,其中包含以下几行:

wwa weweweof ewewe wdw:

      1    11 ms    <1 ms    <1 ms  174.78.134.1  
      2    11 ms    <1 ms    <1 ms  174.78.134.1 
      3     5 ms    <1 ms    <1 ms  x58trxd00.abcd.edu.com [143.71.290.42] 
      4    11 ms    <1 ms    <1 ms  174.78.134.1 

我正在使用

    if(linecount == 8)
    while( fscanf(fp, "%d %s %s %s %s  %s %s",&a1,&a2,&a3,&a4,&a5,&a6,&a7,&a8) != EOF ){  
          printf("%s",ch);
        } 

    else if (linecount == 9){
       while( fscanf(fp, "%d %s %s %s %s  %s %s %s",&a1,&a2,&a3,&a4,&a5,&a6,&a7,&a8,&a9) != EOF ){  
          printf("%s",ch);
       }
    }

如何检查文件中的行是否包含 8 或 9 个元素,以便我可以相应地运行上述 else-if 语句?

【问题讨论】:

    标签: c std scanf


    【解决方案1】:

    使用 fscanf 读取行

    没有。

    但我认为这是个好主意,因为...

    没有。


    使用fgets()函数(read the funny manual)完成读取行:

    char buf[LINE_MAX];
    while (fgets(buf, sizeof buf, file) != NULL) {
        // process line here
    }
    

    然后,您可以使用 sscanf()(非首选)或像 strchr()strtok_r()(首选)这样的健全函数来解析它。还值得一提的是scanf() (docs) 的返回值不是 EOF,而是成功读取的实体数。因此,解析字符串的惰性方法可能是:

    if (sscanf(buf, "%s %s %s %s %s %s %s %s %s", s1, s2, ...) < 9) {
        // there weren't 9 items to convert, so try to read 8 of them only
    }
    

    另请注意,您最好在%s 转换说明符中使用一些长度限制,以避免缓冲区溢出错误,如下所示:

    char s1[100];
    sscanf(buf, "%99s", s1);
    

    同样,在扫描(进入)字符串时,您不应使用&amp; 地址运算符 - char 数组已经衰减为 char *,这正是 %s 转换说明符所期望的 - &amp;s1 的类型是 char (*)[N] 如果 s1 是 N 个 chars 的数组 - 并且类型不匹配会使 scanf() 调用未定义的行为。

    【讨论】:

    • 感谢您的解释,但是如果没有 9 个元素,我应该如何阅读 8 个元素?是使用else if ...&lt;8)吗?
    • @DeepakTivari 您可能包含 8 个转换说明符而不是 9 个?
    • 然而,我的 txt 文件可以包含 9 个元素 8 个甚至更少的元素,例如:9 - 我将在第 9 个元素上获取 IP 地址并存储它,对于案例 8:我会得到第 8 个元素的 IP 地址存储它,基本上重要的是我提取第 8 个或第 9 个元素的 IP 地址而不是其他元素
    • @DeepakTivari 你不懂我...首先尝试转换 9 个项目。如果失败,则尝试转换 8. 等。
    • @DeepakTivari 好吧,你写s9而不是&amp;s9,也许吧?
    【解决方案2】:

    使用fgets 获取该行,然后执行一个sscanf 来检查9 个元素,如果失败则再次使用sscanf 来检查8 个元素行。

    如果行的格式除了一个额外的项目之外是相同的,那么请记住scanf 系列函数返回成功扫描项目的数量。因此,只需调用一次sscanf 并检查它是否返回89 就足够了。

    【讨论】:

      【解决方案3】:

      您必须使用fgets() 函数,因为您数组中的swag 值当前设置为null

      【讨论】:

        【解决方案4】:

        并且不要将&amp;string 类型(字符数组)数据类型与scanf 一起使用

        scanf("%s",name); //use it without "&" sign
        

        原因:

        C 中的“字符串”是字符缓冲区的地址。 您希望 scanf 填充变量指向的缓冲区中的内存。

        相比之下,int 是一块内存,而不是地址。为了让 scanf 填充该内存,您需要传递它的地址。

        【讨论】:

        • 这可能是真的,但您应该解释原因。就目前而言,这只是一个无益的评论。
        猜你喜欢
        • 2017-12-05
        • 1970-01-01
        • 2014-11-29
        • 1970-01-01
        • 2016-02-28
        • 2018-04-07
        • 1970-01-01
        • 1970-01-01
        • 2023-03-26
        相关资源
        最近更新 更多