将数据放入字符串数组时出错

时间:2013-02-18 03:17:31

标签: c arrays string pointers

 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, " "));
}

在此代码中,*字符串部分未按预期执行。每次遍历代码都会覆盖整个字符串数组。 fgets正在读取正确的数据,如果我打印第一个令牌的值,每个循环都会通过,这是我所期望的。在循环之外,(或者如果我打印(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

1 个答案:

答案 0 :(得分: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, " "));
    }
}