【问题标题】:sscanf parse formatted stringsscanf 解析格式化字符串
【发布时间】:2015-04-10 04:58:34
【问题描述】:

我想读取一个包含未定义数量的后缀的字符串,所有后缀由;分隔

示例 1:« .txt;.jpg;.png »

示例 2:« .txt;.ods;_music.mp3;.mjpeg;.ext1;.ext2 »

browsed the web 并写了那段不起作用的代码:

char *suffix[MAX]; /* will containt pointers to the different suffixes */
for (i = 0; i < MAX ; i++)
{
    suffix[i] = NULL;
    if (suffix_str && sscanf(suffix_str,"%[^;];%[^\n]",suffix[i],suffix_str) < 1)
        suffix_str = NULL;
}

第一次迭代后sscanf的结果为0,为什么没有读取到字符串的内容?

应该如何解析包含未定义数量元素的字符串? sscanf是个不错的选择吗?

【问题讨论】:

  • 为什么不使用例如拆分它strtok 而不是?
  • 您正在为源数据使用相同的缓冲区目标参数。 C9899 § 7.21.6.7p2:“如果复制发生在重叠的对象之间,则行为未定义。” - ......就这么多。回到绘图板。
  • suffix_str 是否以某种方式在对 sscanf 的单次调用中同时处理两个 不同 非重叠缓冲区,其中它同时显示为源缓冲区 和 第二个目标参数?是的,我确定。我不相信这是您的 only 问题,但是看到它会调用未定义的行为,无论如何您都不能依赖任何东西。修复它:使用中间临时缓冲区并在成功时复制回。
  • ...我也认为strtok 是一条更好的旅行方式(同意 Joachim 的观点)。
  • 这不是您应该使用 sscanf() 的方式。如果要存储指针,请使用strtok() 或简单地编写自己的循环来标记指针。

标签: c parsing scanf


【解决方案1】:

首先,正如一般评论中所述,您通过使用相同的缓冲区作为sscanf 的源输入和目标目标来调用未定义的行为。根据 C 标准,这是不允许的。

为此使用的正确函数可能是strtok。下面是一个非常简单的例子。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
    char line[] = ".txt;.ods;_music.mp3;.mjpeg;.ext1;.ext2";
    size_t slen = strlen(line); // worst case
    char *suffix[slen/2+1], *ext;
    size_t count=0;

    for (ext = strtok(line, ";"); ext; ext = strtok(NULL, ";"))
        suffix[count++] = ext;

    // show suffix array entries we pulled
    for (size_t i=0; i<count; ++i)
        printf("%s ", suffix[i]);
    fputc('\n', stdout);
}

输出

.txt .ods _music.mp3 .mjpeg .ext1 .ext2 

备注

  • 此代码假定最坏情况的后缀计数为字符串长度的一半,因此单个字符后缀的列表在分隔符上拆分。
  • 后缀数组包含指向现在切片的原始行缓冲区的指针。因此,这些指针的可用性生命周期仅与行缓冲区本身一样长。

希望对你有帮助。

【讨论】:

    【解决方案2】:

    有几种方法可以对 C 字符串进行标记。除了使用strtoksscanf,你还可以这样做:

    char *temp = suffix_str;
    char *suffix[i];
    for (int i = 0; i < MAX; i++)
    {
        int j = 0;
        char buf[32];
        while (*temp != '\0' && *temp != '\n' && *temp != ';')
        {
            buf[j++] = *temp;
            temp++;
        }
        buf[j] = 0;
    
        if (*temp == ';') temp++;
    
        suffix[i] = malloc((strlen(buf) + 1) * sizeof(char));
        //handle memory allocation error
        strcpy(suffix[i], buf);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多