c - 如何从缓冲区中逐字读取仅由 ":"分隔的内容?

标签 c buffer

我正在制作一个语言翻译器,想要从缓冲区中逐字读取并将它们存储在键值结构中。

缓冲区包含这样一个文件:

hola:hello
que:what

等等。我已经尝试了所有方法,但仍然出现诸如段错误:11之类的错误,或者只是一遍又一遍地读取同一行。

struct key_value{
char *key;
char *value;
};

...

struct key_value *kv = malloc(sizeof(struct key_value) * count);
char k[20]; //key
char v[20]; //value
int x = 0;
for(i = 0; i < numbytes; i++){
    sscanf(buffer,"%21[^:]:%21[^\n]\n",k,v);
    (kv + i)->key = k;
    (kv + i)->value = v;
}

for(i = 0; i < count; i++){
    printf("key:  %s, value:  %s\n",(kv + i)->key,(kv + i)->value);
}

free(buffer);
free(kv);

我期望输出为key:hola,value:hello key:que,value:what, 但实际的输出只是一遍又一遍的key: Hola, value: hello

哪种方法是正确的?

最佳答案

您的代码存在多个问题,其中

  • 在每次循环迭代中,您都从缓冲区的开头进行读取。那么,每次迭代都会提取相同的键和值,这是很自然的。

  • 更一般地说,您的读取循环迭代变量似乎与读取的数据没有关系。它似乎是每字节迭代,但您似乎想要每迭代。您可能想查看scanf%n指令来帮助您跟踪缓冲区的进度。

  • 您正在将每个键/值对扫描到同一个本地 kv变量,然后您将指向这些变量的指针分配给您的结构。生成的指针都是相同的,并且当函数返回时它们将变得无效。我建议给struct key_value` 数组作为其成员而不是指针,并将数据复制到其中。

  • 您的sscanf format 最多可为键和值读取 21 个字符,但提供的目标数组不够长。您需要将它们的尺寸设置为至少 22 个字符,以容纳 21 个字符加上字符串终止符。

  • 您的sscanf()格式和用法不支持识别格式错误的输入,尤其是超长的键或值。您需要检查返回值,并且可能需要将尾随换行符与 %c 相匹配。字段(格式中的文字换行符并不代表您所认为的含义)。

使用 strtok_r 标记化(整个缓冲区)或strtok甚至 strchr而不是sscanf()对你来说可能会更容易。

此外,样式注释:您的表达式 (kv + i)->key 形式是有效的,但写 kv[i].key 会更惯用。 .

关于c - 如何从缓冲区中逐字读取仅由 ":"分隔的内容?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56970964/

相关文章:

CC\GCC 编译后的可执行文件无法在我的机器上运行?

c - opengl 无法绘制网格

c - 如何使用按位运算符表示否定,C

c - 使用指针访问二维数组

ios - 如何确定AVAssetWriter中样本缓冲区使用的持续时间

c - 数组指针的初始化

c - scanf/getchar 只有第一次通过循环才能正常工作吗?

python - 避免缓冲读取 "for line in ..."

c - 输入更多字符会跳过提示

C# 创建缓冲区溢出