Megan B
Megan B

Reputation: 117

fscanf read access segfault

I a successfully open a file that contains initial key-value pairs. The code looks like this:

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);

When I run i get:

key tmp is y? value tmp is 1

then it segfaults. When I change access to "w" the code sets zmu.cfg file size to 0 and i get:

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

no segfault... Interestingly enough, once the file is 0 bytes I can change the access back to "r" it no longer segfaults and i get:

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

I believe this has something to do with the way fscanf works. Does fscanf delete the line from the file when it scans? All I am trying to do is get a key-value pair from a text file. I dont think i can use fread because the keys dont always have the same size. I do NOT want the file modified, any thoughts?

zmu.cfg looks like this:

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

MessageNum= message50
VarOne= 0x02
VarTwo= 0x01

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

Upvotes: 1

Views: 106

Answers (3)

Megan B
Megan B

Reputation: 117

Yay! I changed the last lines to this:

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);

and I get:

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

Thanks for looking at my code, didn't think i needed to pass the address of key_tmp to fscanf for %i since I did not have to for %s.

Upvotes: 0

David C. Rankin
David C. Rankin

Reputation: 84569

You experience undefined behavior on your first call to:

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

Neither key_tmp or value_tmp are initialized to any value. After you attempt to access the uninitialized values, all bets are off. Your code could give you some output, or it could segfault -- you are experiencing undefined behavior -- anything could happen.

Further, if you are reading an int in value_tmp, your fscanf format string should be:

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

Upvotes: 0

R Sahu
R Sahu

Reputation: 206667

You haven't initialized key_tmp before using it here.

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

You are passing the wrong argument to fscanf. Casting value_tmp to char* does not enable it to hold a string.

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

If the file contains an integer, use:

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

If the file contains a string, make sure that value_tmp is a string large enough to hold the data.

char value_temp[1000];

and then, use:

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

Upvotes: 1

Related Questions