【问题标题】:Why does my variable change after strtok() and fgets() without modifying it?为什么我的变量在 strtok() 和 fgets() 之后发生变化而不修改它?
【发布时间】:2015-06-19 09:28:06
【问题描述】:

这里的问题演示:http://goo.gl/71U1xA

我正在读取一个文件,在那个文件中有一行:

SECTIE FIELD_IN #define ENDSEC

这表明我需要将这一行之后的行存储到一个变量中,但如果该行包含“#define”部分。

所以,我正在遍历文件,当该行包含“SECTIE”和“FIELD_IN”时,它会检索其中包含# 的单词并将其存储在变量keyWord 中。

现在的问题是:keyWord 中的值会在下一个循环中发生变化,而无需修改它。

我的文本文件是:

SECTIE FIELD_IN1 #define ENDSEC
#define COL1                1,1
#define COL2                2,3
#define COL3                5,3
...etc

我的代码的输出是这样的:

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
.

我的代码:

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++;
    }       
}

我认为这与while (fgets(inputLine, sizeof(inputLine), iFile) != NULL) 有关,因为在执行该行之后,值会发生变化。

为什么进入下一个循环后keyWord的值会改变?我猜这与未定义的行为有关,但我无法解决这个问题。

【问题讨论】:

  • 你知道指针是如何工作的吗?

标签: c file text undefined-behavior c-strings


【解决方案1】:

你有 inputLine 这是一个数组。在其中存储fgets()获取的字符串:

while (fgets(inputLine, sizeof(inputLine), iFile) != NULL){

在你的循环中,你说keyWord 指向某个 inputLine 的标记(这意味着它指向你数组中的某个地方)。

//get keyword
keyWord = strtok(inputLine," ");

当您运行第二个fgets() 时,数组内容的变化,但不是它的地址,所以 keyWord 仍然指向 inputLine 内容的已经改变了

例子:

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)

你假设“keyWord的值改变了”是假的:关键字的值还是一样的,你可以用printf("value of keyWord: %p\n", keyWord);检查。改变的是值keyWord指向,这是您在 printf 中使用%s 显示的内容。

【讨论】:

    【解决方案2】:

    strtok 修改输入缓冲区。所以你在循环结束时得到的keyword 是一个指向inputLine 中位置的指针。当循环使用fgets 读取另一行时,它会被覆盖。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-27
      • 2017-05-09
      • 1970-01-01
      • 1970-01-01
      • 2015-04-08
      • 2022-11-26
      • 1970-01-01
      • 2021-12-18
      相关资源
      最近更新 更多