我想读取一个文件并将每一行写入char数组。由于我不知道线的数量,因此我认为最有效的方法是使用二维数组的char指针。但是我得到了分段错误。
我的问题可能与此问题重复: 2D array of char pointers --> Segmentation fault?
但我无法确定C的正确语法,所以我无法尝试。
这是我的代码:
FILE *file = fopen ( filename, "r" );
if ( file != NULL )
{
char line [ 128 ]; /* or other suitable maximum line size */
char **new_line;
int i = 0;
while ( fgets ( line, sizeof line, file ) != NULL ) /* read a line */
{
strcpy(new_line[i], line);
i++;
}
答案 0 :(得分:2)
没有为导致分段错误的new_line
分配内存。
如果您知道没有行,那么您可以将其声明为本地数组本身。在这种情况下,您的访问方法将正常工作。
#define MAX_LINES 20
#define MAX_CHARS 128
...
char new_line[MAX_LINES][MAX_CHARS] = {0};
...
你的问题是你不知道最大行数。所以你选择了双指针。在这种情况下,您需要先malloc
行n
行,然后您需要继续使用realloc
来增加缓冲区大小。
#define MAX_CHARS 128
#define N_NO_OF_LINES 10
...
char line[MAX_CHARS] = {0};
char **new_line = NULL;
int noOfLines = 0;
int lineCount = 0;
new_line = malloc(sizeof(char*) * N_NO_OF_LINES);
noOfLines = N_NO_OF_LINES;
while (fgets (line, sizeof line, file) != NULL) /* read a line */
{
if (lineCount >= noOfLines)
{
new_line = realloc(new_line, (sizeof(char*)*(noOfLines+N_NO_OF_LINES)));
noOfLines += N_NO_OF_LINES;
}
new_line[lineCount] = strdup(line);
lineCount++;
}
注意:对malloc
和realloc
答案 1 :(得分:1)
new_line未初始化为有效的内存块。
大致是:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main() {
FILE *file = fopen ( "test.txt", "r" );
if ( file != NULL )
{
#define MAXLINES 128
#define MAXLINELEN 100
char line [ MAXLINELEN ]; /* or other suitable maximum line size */
char **new_line = (char **)malloc(sizeof(char *) * MAXLINES);
int i = 0;
if (!new_line) exit(-1);
while ( i < MAXLINES && (fgets ( line, sizeof line, file ) != NULL )) /* read a line */
{
new_line[i] = strdup(line);
i++;
}
printf("read %d lines\n", i);
}
exit(0);
}
答案 2 :(得分:0)
您没有为new_line
数组分配任何内存。你需要这样的东西:
char **new_line = malloc(sizeof(char *) * MAX_LINES);
然后对于每一行,不要使用strcpy
,它将复制到垃圾指针(未初始化的new_line
数组)。您可能需要strdup(3)
:
new_line[i] = strdup(line);
答案 3 :(得分:0)
您将new_line
声明为指向char *
的指针,但它永远不会被初始化,因此它指向一些无效的内存地址。写入该地址时会出现错误。
您可能希望分配内存,将其分配给new_line
,然后您可以将字符串复制到其中。
答案 4 :(得分:0)
您需要为字符串分配空间。 Malloc返回一个具有您想要的大小的内存插槽,但不允许重新分配内存。为此你有realloc。
使用malloc,你最终会得到一个固定大小的表,就像你只声明它有静态但后来初始化一样(好吧,我再说一遍这句话因为malloc远不止于此,但为了这个目的,它是安全的说。)
Realloc这样做,重新分配内存,但如果你没有正确使用我,那就非常危险了。而且,在我看来,这不是最正确的方法。
如果您想保存一些您不了解尺寸的东西,那么动态结构就是您的选择。 您可以使用&#39;链接列表,例如&#39;数据结构,因此您可以拥有任意数量的单词,然后将该列表转换为数组。
我会选择这样的东西:
typedef struct _words{ //Structure to the dynamic insertion of words
char *word;
struct _words *next;
}words;
words *last; //Easier implementation for this case. Not always the best solution
words *init(){ //Is good practice to start with an empty structure for reference passing
words *new = malloc(sizeof(words));
if(new == NULL) exit(0);
new->next = NULL; //A good end/next reference
return new;
}
void insertWord(char *word){
words *new = malloc (sizeof(words));
if(new == NULL) exit(0);
new->word = malloc(strlen(word)*sizeof(char));
if(new->word == NULL) exit(0);
new->next = NULL; //Or new->next = last->next; wich is also null.
last->next = new;
last = new;
}
int main(){ //Or the name of your function
FILE *file = fopen ( filename, "r" );
words *list = init();
last = list;
if ( file != NULL )
{
char line [ 128 ]; /* or other suitable maximum line size */
int i = 0;
while ( fgets ( line, sizeof line, file ) != NULL ) /* read a line */
{
insertWord(line);
i++;
}
//Here, you already have all the words in your dynamic structure. You can now save them into an array
char **array = malloc(i*sizeof(char*)); //i is the number of words.
if(array == NULL) exit(0);
word *aux = list->next;
if(aux != NULL){
for(int j=0;j<i && aux != NULL;j++){
array[j] = malloc(strlen(aux->word)*sizeof(char));
if(array[j] == NULL) exit(0);
strcpy(array[j], aux->word);
aux = aux->next; // jump to the next word
}
}
...
}
我认为这可能有效,但我没有尝试过。只是为了让您了解如何实现动态结构。
它错过了释放并且不是真正的堆栈,即使它已经接近了。
希望这会有所帮助。