fscanf读取访问段错误

时间:2014-12-23 22:03:44

标签: c ubuntu file-io scanf

我成功打开了一个包含初始键值对的文件。代码如下所示:

char key_tmp[30];
int value_tmp, status_index;

FILE *ZMU_Init_fd = NULL;
ZMU_Init_fd = fopen("zmu/zmu.cfg", "r");

if(ZMU_Init_fd ==  NULL)
{
    printf("Could not open file");
    strerror(errno);
}

printf("key tmp is %s, value tmp is %d\n", key_tmp, value_tmp);
fscanf(ZMU_Init_fd, "%s %s", key_tmp, (char *)value_tmp);
printf("key tmp is %s, value tmp is %d\n", key_tmp, value_tmp);

当我跑步时,我得到:

key tmp is y? value tmp is 1

然后是段错误。当我更改对“w”的访问时,代码将zmu.cfg文件大小设置为0并且我得到:

key tmp is y? value tmp is 1
key tmp is y? value tmp is 1

没有段错误...有趣的是,一旦文件为0字节,我可以将访问权限更改为“r”,它不再是段错误,我得到:

key tmp is y? value tmp is 1
key tmp is y? value tmp is 1

我认为这与fscanf的工作方式有关。 fscanf在扫描时是否从文件中删除该行?我想要做的就是从文本文件中获取一个键值对。我不认为我可以使用fread因为键不总是具有相同的大小。我不想修改文件,有什么想法吗?

zmu.cfg看起来像这样:

MessageNum= message50
MsgInitOne= 0x01
MsgInitTwo= 0x04
MsgInitThree= 0x01

MessageNum= message50
VarOne= 0x02
VarTwo= 0x01

MessageNum= message50
MsgValOne= 0x01
MsgValTwo= 0x04
MsgValThree= 0x02

3 个答案:

答案 0 :(得分:1)

在此处使用之前,您尚未初始化key_tmp

printf("key tmp is %s, value tmp is %d\n", key_tmp, value_tmp);

您将错误的参数传递给fscanf。将value_tmp投射到char*不会使其保留字符串。

fscanf(ZMU_Init_fd, "%s %s", key_tmp, (char *)value_tmp);

如果文件包含整数,请使用:

fscanf(ZMU_Init_fd, "%s %d", key_tmp, &value_tmp);

如果文件包含字符串,请确保value_tmp是一个足以容纳数据的字符串。

char value_temp[1000];

然后,使用:

fscanf(ZMU_Init_fd, "%s %s", key_tmp, value_tmp);

答案 1 :(得分:0)

您在第一次致电时遇到未定义的行为

printf("key tmp is %s, value tmp is %d\n", key_tmp, value_tmp);

key_tmpvalue_tmp都未初始化为任何值。尝试访问未初始化的值后,所有投注均已关闭。您的代码可能会给您一些输出,或者它可能会出现段错误 - 您遇到未定义的行为 - 任何事情都可能发生。

此外,如果您正在int中阅读value_tmp,则您的fscanf格式字符串应为:

fscanf(ZMU_Init_fd, "%s %d", key_tmp, &value_tmp);

答案 2 :(得分:0)

耶!我把最后几行更改为:

fscanf(ZMU_Init_fd, "%s %s", key_tmp, key_tmp);
printf("key tmp is %s, value tmp is %d\n", key_tmp, value_tmp);
fscanf(ZMU_Init_fd, "%s %x", key_tmp, &key_tmp);
printf("key tmp is %s, value tmp is %d\n", key_tmp, value_tmp);

我得到了:

key tmp is message50 value tmp is 8388608
key tmp is MsgInitOne value tmp is 1

感谢您查看我的代码,我认为我不需要将key_tmp的地址传递给fscanf for%i,因为我没有使用%s。