Reputation: 4669
Demonstration of the problem here: http://goo.gl/71U1xA
I am reading a file, and in that file there is a line:
SECTIE FIELD_IN #define ENDSEC
that indicates I need to store the lines following this one to a variable, but only if the line contains the part "#define
".
So, I'm iterating trough the file and when the line contains "SECTIE
" and "FIELD_IN
", it retrieves the word with #
in it and it stores it in the variable keyWord
.
Now the problem is: the value in keyWord
changes in the next loop without modifying it.
My textfile is:
SECTIE FIELD_IN1 #define ENDSEC
#define COL1 1,1
#define COL2 2,3
#define COL3 5,3
...etc
And the output of my code is this:
START reading line text=SECTIE FIELD_IN1 #define ENDSEC keyword1=.. new sectie keyword2=.#define. reading line text=#define COL1 1,1 keyword1=. 1,1 . start = 1! keyword3=. 1,1 .
My code:
int x, status, start;
char inputLine[5000 + 1];
char copyLine[5000 + 1];
char *keyWord = "";
FILE *iFile;
status = NOERROR;
x = 0;
start = 0;
iFile = fopen(gsz_inputFile, "r");
if(iFile == NULL){
status = ER_OPEN;
return status;
}
while (fgets(inputLine, sizeof(inputLine), iFile) != NULL){
printf("\n\nreading line");
printf("\ntext=%s", inputLine);
printf("\nkeyword1=.%s.", keyWord);
strcpy(copyLine, inputLine);
strlwr(copyLine);
if(strstr(copyLine, "sectie") != NULL && strstr(copyLine, "field_in") != NULL){
start = 1;
printf("\nnew sectie");
//get keyword
keyWord = strtok(inputLine," ");
while (keyWord != NULL)
{
if(strstr(keyWord, "#") != NULL){
break;
}
keyWord = strtok(NULL, " ");
}
printf("\nkeyword2=.%s.", keyWord); //here the keyword is correct
continue;
}
if(start){
printf("\nstart = 1!");
printf("\nkeyword3=.%s.", keyWord);
//status = storeString(inputLine, keyw, x); //my actual code is different
if(status != NOERROR){ x--; }
x++;
}
}
I think it has something to do with while (fgets(inputLine, sizeof(inputLine), iFile) != NULL)
because after that line is executed, the value is changed.
Why is the value of keyWord
changed after going into the next loop? My guess it has to do with undefined behavior, but I can't put my finger on the problem.
Upvotes: 2
Views: 654
Reputation: 4366
You have inputLine
which is an array. Inside it you store the string fetched by fgets()
:
while (fgets(inputLine, sizeof(inputLine), iFile) != NULL){
And in your loop you say keyWord
points to some inputLine's token (which means it points to somewhere inside your array).
//get keyword
keyWord = strtok(inputLine," ");
When you run the second fgets()
the array content's change, but not its address, so keyWord still points to inputLine content's which have changed
Example:
first fgets():
inputLine: ['H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd']
keyWord-->""
second strtok:
keyWord------------------------------------^
second fgets():
inputLine: ['T', 'h', 'i', 's', ' ', 'c', 'h', 'a', 'n', 'g', 'e']
keyword------------------------------------^ (before strtok)
You assumption "The value of keyWord
changed" is false: The value of keyword is still the same, you can check it with printf("value of keyWord: %p\n", keyWord);
. What changed is the value keyWord
points to, which is what you display using %s
in printf.
Upvotes: 4
Reputation: 121427
strtok
modifies the input buffer. So the keyword
you get at the end of the loop is a pointer to location within the inputLine
. When the loop reads another line using fgets
it gets overwritten.
Upvotes: 3