我正在制作一个语言翻译器,想要从缓冲区中逐字读取并将它们存储在键值结构中。
缓冲区包含这样一个文件:
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
指令来帮助您跟踪缓冲区的进度。您正在将每个键/值对扫描到同一个本地
k
和v
变量,然后您将指向这些变量的指针分配给您的结构。生成的指针都是相同的,并且当函数返回时它们将变得无效。我建议给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/