结构数组 - C 错误值
Array of structs - C bad value
我在 C 中遇到了一个非常有趣的问题。
所以我有一个看起来像这样的结构:
struct Question {
int year;
char* month;
char* day;
char* hour;
char* minute;
char* second;
char* question;
int answerCount;
char* answers[1024];
} questions[100];
在那里,我正在初始化一个名为 questions 的 Question 结构数组,大小为 100。
所以我想从这样的文件中填充该数组:
2017 04 01 12 38 00 OK? 2 NO NO
2017 04 01 14 15 00 WHAT? 4 YES YES YES YES
结构:
年月日时分第二题answercount answers
我正在这样处理文件:
...
int id = 0;
int j;
char line[2048];
while ( (fgets(line, sizeof(line), fp)) != NULL) {
char* p = strtok(line, " ");
char* tokens[1024];
char* token;
int i = 0;
int counter = 0;
while((p != NULL)) {
switch(counter) {
case 0: questions[id].year = atoi(p); break; // year
case 1: questions[id].month = p; break; // month
case 2: questions[id].day = p; break; // day
case 3: questions[id].hour =p; break; // hour
case 4: questions[id].minute = p; break; // minute
case 5: questions[id].second = p; break; // seconds
case 6: questions[id].question = p; break; // question
case 7:
questions[id].answerCount = atoi(p);
int qcount = atoi(p);
int k;
int l = j;
//printf("count : %d", qcount);
for (k = 0; k < qcount; ++k) {
p = strtok(NULL, " ");
++l;
questions[id].answers[k] = p;
}
break;
default: break;
}
p = strtok(NULL, " ");
++counter;
}
++id;
}
fclose(fp);
...
之后,如果我在 while 循环中打印 questions[0].question 元素,我会得到 "OK?",但是如果我在 while 循环后打印相同的内容,我会得到 "WHAT?".
我花了很多时间思考我可能做错了什么,但没有成功。
感谢您的帮助。
这个:
char* answers[1024];
是一个包含 1024 个字符串指针的数组,但不包含对这些字符串的任何存储。所以当你这样做时:
questions[id].answers[k] = p;
您不是在复制答案,而只是分配一个指向它的指针。由于 p
最终是指向 line
中某处的指针,它仅在循环开始前分配一次,因此每次循环都会覆盖 line
中的字符串。所以你的 answers
的引用正在被修改。
您可以将 answers
更改为 char 的二维数组,在这种情况下每个答案的最大长度将受到限制,或者使用 strdup()
或类似的方法为每个答案分配内存, 最后 free()
它。
在您的结构中,您有许多字符指针,您正在为所有这些指针分配从 strtok
返回的指针值。您需要了解 strtok
返回的指针内容会随着每次调用 strtok
而改变,您不应该存储这些指针以备将来使用。参考strtok的man.
您需要将结构中的 char *
更改为 char
数组或为那些 char *
分配内存,然后将指针的内容复制到 [=10] 返回的指针=] 到它。否则你的程序可能会出现奇怪的行为。
我在 C 中遇到了一个非常有趣的问题。 所以我有一个看起来像这样的结构:
struct Question {
int year;
char* month;
char* day;
char* hour;
char* minute;
char* second;
char* question;
int answerCount;
char* answers[1024];
} questions[100];
在那里,我正在初始化一个名为 questions 的 Question 结构数组,大小为 100。
所以我想从这样的文件中填充该数组:
2017 04 01 12 38 00 OK? 2 NO NO
2017 04 01 14 15 00 WHAT? 4 YES YES YES YES
结构: 年月日时分第二题answercount answers
我正在这样处理文件:
...
int id = 0;
int j;
char line[2048];
while ( (fgets(line, sizeof(line), fp)) != NULL) {
char* p = strtok(line, " ");
char* tokens[1024];
char* token;
int i = 0;
int counter = 0;
while((p != NULL)) {
switch(counter) {
case 0: questions[id].year = atoi(p); break; // year
case 1: questions[id].month = p; break; // month
case 2: questions[id].day = p; break; // day
case 3: questions[id].hour =p; break; // hour
case 4: questions[id].minute = p; break; // minute
case 5: questions[id].second = p; break; // seconds
case 6: questions[id].question = p; break; // question
case 7:
questions[id].answerCount = atoi(p);
int qcount = atoi(p);
int k;
int l = j;
//printf("count : %d", qcount);
for (k = 0; k < qcount; ++k) {
p = strtok(NULL, " ");
++l;
questions[id].answers[k] = p;
}
break;
default: break;
}
p = strtok(NULL, " ");
++counter;
}
++id;
}
fclose(fp);
...
之后,如果我在 while 循环中打印 questions[0].question 元素,我会得到 "OK?",但是如果我在 while 循环后打印相同的内容,我会得到 "WHAT?".
我花了很多时间思考我可能做错了什么,但没有成功。
感谢您的帮助。
这个:
char* answers[1024];
是一个包含 1024 个字符串指针的数组,但不包含对这些字符串的任何存储。所以当你这样做时:
questions[id].answers[k] = p;
您不是在复制答案,而只是分配一个指向它的指针。由于 p
最终是指向 line
中某处的指针,它仅在循环开始前分配一次,因此每次循环都会覆盖 line
中的字符串。所以你的 answers
的引用正在被修改。
您可以将 answers
更改为 char 的二维数组,在这种情况下每个答案的最大长度将受到限制,或者使用 strdup()
或类似的方法为每个答案分配内存, 最后 free()
它。
在您的结构中,您有许多字符指针,您正在为所有这些指针分配从 strtok
返回的指针值。您需要了解 strtok
返回的指针内容会随着每次调用 strtok
而改变,您不应该存储这些指针以备将来使用。参考strtok的man.
您需要将结构中的 char *
更改为 char
数组或为那些 char *
分配内存,然后将指针的内容复制到 [=10] 返回的指针=] 到它。否则你的程序可能会出现奇怪的行为。