-1
 void readit(FILE* filePtr, int* num1, int* num2, char** strings, int lines)
     {
int t;
char line[50];

for (t = 0; t < lines; t++){
    fgets(line, 50, filePtr);
    *(strings + t) = strtok(line, " "));
    *(num2 + t) = atoi(strtok(NULL, " "));
    *(num2 + t) = atoi(strtok(NULL, " "));
}

在此代码中,*strings 部分未按预期执行。每次通过代码都会覆盖整个字符串数组。fgets 正在读取正确的数据,如果我打印第一个令牌的值,则每个循环都符合我的预期。在循环之外,(或在 if i print (i - 1) 所有数组 *str + 1、*str + 2 等内部)将包含最后一次通过的值。

例如。

         *(strings + 0) = "Hi";
         printf("%s", *(strings + 0)); //Will print hi

         //next iteration
         *(strings + 1) = "You";
         printf("%s", *(strings + 1)); // will print you
         printf("%s", *(strings + 0)); // will print you as well
4

1 回答 1

2

问题是您只有一个不断被覆盖的字符串缓冲区。记住strtok不分配新内存它返回一个指向它传递的缓冲区的指针。每次通过循环strtok*(strings + t) = line。然后在下一个循环中,您将日期覆盖在line. 你最终得到的是一个 char 指针数组,它们都指向同一个字符串缓冲区。(您还返回一个指向局部变量的指针,这是未定义的行为)

您的代码相当于以下内容:

    char *strings[2];
    char line[50];
    strcpy(line, "Hi");
    *(strings + 0) = line;
     printf("%s", *(strings + 0)); //Will print hi

     //next iteration
     strcpy(line, "You");
     *(strings + 1) = line;
     printf("%s", *(strings + 1)); // will print you
     printf("%s", *(strings + 0)); // will print you as well

因此,两者当然strings+0string+1指出line要改变strings+0打印的内容。

您要么需要动态分配内存,要么需要以可以strcpy进入的缓冲区为基础。例如:

char strings[5][50];
readit(filtPtr, &num1, &num2, strings, 50);

...

void readit(FILE* filePtr, int* num1, int* num2, char** strings, int lines)
{
     int t;
     char line[50];

    for (t = 0; t < lines; t++){
        fgets(line, 50, filePtr);
        strcpy(*(strings + t), strtok(line, " ")));
        *(num2 + t) = atoi(strtok(NULL, " "));
        *(num2 + t) = atoi(strtok(NULL, " "));
    }
}
于 2013-02-18T03:59:02.293 回答