[英]C, values in array of pointers dissapear (pointers)
我似乎在这里失去了对我的指针的引用。 我不知道为什么,但我怀疑是 fgets 返回的指针把事情搞砸了。 有人告诉我从文件中读取单词的一种好方法是获取行然后用笔划分隔单词,但是如果我在 words[i] 中的指针不断消失,我该怎么办呢?
文本
Natural Reader is
john make tame
结果我得到了。
array[0] = john
array[1] = e
array[2] =
array[3] = john
array[4] = make
array[5] = tame
int main(int argc, char *argv[]) {
FILE *file = fopen(argv[1], "r");
int ch;
int count = 0;
while ((ch = fgetc(file)) != EOF){
if (ch == '\n' || ch == ' ')
count++;
}
fseek(file, 0, SEEK_END);
size_t size = ftell(file);
fseek(file, 0, SEEK_SET);
char** words = calloc(count, size * sizeof(char*) +1 );
int i = 0;
int x = 0;
char ligne [250];
while (fgets(ligne, 80, file)) {
char* word;
word = strtok(ligne, " ,.-\n");
while (word != NULL) {
for (i = 0; i < 3; i++) {
words[x] = word;
word = strtok(NULL, " ,.-\n");
x++;
}
}
}
for (i = 0; i < count; ++i)
if (words[i] != 0){
printf("array[%d] = %s\n", i, words[i]);
}
free(words);
fclose(file);
return 0;
}
strtok 不分配任何 memory,它返回一个指向缓冲区中分隔字符串的指针。
因此,如果要在循环迭代之间保留单词,则需要为结果分配 memory
例如
word = strdup(strtok(ligne, " ,.-\n"));
您还可以通过为读取的每一行使用唯一的ligne
来处理这个问题,因此将其设为一个字符串数组,如下所示:
char ligne[20][80]; // no need to make the string 250 since fgets limits it to 80
然后您的 while 循环更改为:
int lno = 0;
while (fgets(ligne[lno], 80, file)) {
char *word;
word = strtok(ligne[lno], " ,.-\n");
while (word != NULL) {
words[x++] = word;
word = strtok(NULL, " ,.-\n");
}
lno++;
}
根据文件最大大小的需要调整第一个下标,或者如果您不想要这么低的限制,则在每次迭代期间动态分配行缓冲区。 如果您的实现支持,您也可以使用getline
而不是fgets
; 它可以处理分配,尽管您需要在完成后释放这些块。
如果您正在处理真实世界的散文,您可能希望在列表中包括其他分隔符,如冒号、分号、感叹号和问号。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.