我似乎在这里失去了对我的指针的引用。我不知道为什么,但我怀疑是 fgets 返回的指针搞砸了。 有人告诉我,从文件中读取单词的一个好方法是获取行,然后用 strok 分隔单词,但是如果我在单词 [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] = %sn", i, words[i]);
}
free(words);
fclose(file);
return 0;
}
>strtok 不分配任何内存,它返回指向缓冲区中分隔字符串的指针。
因此,如果要在循环迭代之间保留单词,则需要为结果分配内存
例如
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
;它可以处理分配,尽管您需要在完成后释放块。
如果要处理现实世界的散文,则可能需要在列表中包含其他分隔符,如冒号、分号、感叹号和问号。