我想从文本文件中获取所有行,并将它们存储在我的char**
指针(字符串数组)中。问题是,当我尝试为指针的字符串设置索引时,程序将为所有索引分配最后扫描的句子。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LINE 10000
int main()
{
FILE *fp = NULL;
char line[MAX_LINE];
char** lines = (char**) malloc(10000*200*sizeof(char));
int count = 0;
fp = fopen("test.txt","r");
while(fgets(line,10000,fp)) {
lines[count] = line;
count++;
}
fclose(fp);
for(int i =0; i<2000;i++){
printf("%s",lines[i]);
}
return 0;
}
让我们假设test.txt是这样的:
Alice was beginning to get very tired of sitting by her sister on the
bank, and of having nothing to do: once or twice she had peeped into the
book her sister was reading, but it had no pictures or conversations in
it, and what is the use of a book, thought Alice without pictures or
conversations?
当我这样打印时,每次我在文本文件中得到最后一句话(在这种情况下为conversations?
)。但是,我想将文本文件中的每个扫描语句设置为char **中的不同索引。例如,我要这样设置:
lines[0] gives "Alice was beginning to get very tired of sitting by her sister on the"
lines[1] gives "bank, and of having nothing to do: once or twice she had peeped into the"
and so on.
您不能仅通过分配一个指针就将字符从一个字符串缓冲区复制到另一个字符串(所有操作都是使目标指向源,如您所注意到的那样。
相反,实际上必须使用strcpy
功能复制字符。因此,而不是:
lines[count] = line; // Just makes each pointer point to the same buffer
用途:
strcpy(lines[count], line); // Copies the CURRENT contents of "line"
使用char** lines
缓冲区的方式也存在严重问题。如果需要200行的数组,每行的最大长度为10000个字符,则应按以下方式分配它们:
char** lines = malloc(200 * sizeof(char*)); // Make 200 pointers
// Now allocate 10000 chars to each of these pointers:
for (int i = 0; i < 200; ++i) lines[i] = malloc(10000 * sizeof(char));
注意:200个缓冲区将未初始化(包含随机数据),因此,在打印循环中,应仅将复制了真实数据的缓冲区用作缓冲区,并使用count
变量作为循环限制:
for(int i = 0; i < count; i++) {
printf("%s", lines[i]);
}
此外,别忘了在完成后释放分配的内存:
for (int i = 0; i < 200; ++i) free(lines[i]); // Free each line buffer...
free(lines); // ... then free the array of pointers itself
strdup解决了这个问题,完成时如Adrian所说的那样释放了资源。
int main()
{
FILE *fp = NULL;
char line[MAX_LINE];
char** lines = (char**) malloc(10000*200*sizeof(char));
int count = 0;
fp = fopen("test.txt","r");
while(fgets(line,10000,fp)) {
lines[count] = strdup(line);
count++;
}
fclose(fp);
for(int i =0; i<count;i++){
printf("%s",lines[i]);
}
for (int i = 0; i < count; ++i) free(lines[i]);
free(lines);
return 0;
}
如果您想获得更好的性能,请查看我的仓库(https://github.com/PatrizioColomba/strvect)