如何在c中的数组指针上加载txt
How to load txt on array pointers in c
嘿,我需要一些帮助,我正在尝试在我的 C 程序中加载字典,但出现了段错误。我会喜欢一些帮助。
在使用 gdb 进行调试时,它表示它在第 63 行失败,该命令显示:lines[i]=string_coppied
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
const int step=200;
char **loadfile();
int main()
{
char **words=loadfile();
if (words==NULL) printf ("cant build structure");
for (int i=0 ; i<100 ; i++) printf("%s \n" , words[i] );
}
char **loadfile()
{
//We load our text file at the stack
FILE * fpointer;
fpointer = fopen ("word.txt" , "r");
if (fpointer==NULL) printf ("file not loaded \n");
else printf ("File loaded \n");
int array_size=step;
char ** lines=(char **)malloc(array_size*sizeof(char*));
if (lines=NULL) printf ("cant allocate memory \n");
char temp[100];
int i=0;
while (fgets(temp,100,fpointer))
{
//we check if the already allocated memory is full , if so we realloc
if (i==array_size)
{
array_size +=step;
char **newlines= (char**)realloc(lines , array_size * sizeof(char*));
if (newlines==NULL) //check if the memory was allocated
{
printf ("Cant reallocate memory , please try again \n ");
return 0 ;
}
lines=newlines;
}
//now that we made sure that the memory was allocated we continue by copying the temp //
temp[strlen(temp)-1]="[=10=]" ;
int length =strlen(temp);
char * string_coppied=malloc((length+1) * sizeof(char));
strcpy(string_coppied ,temp);
lines[i]=string_coppied;
i++;
}
return lines;
free(lines);
fclose(fpointer);
}
gdb it says that it failed on line 63 which the command says : lines[i]=string_coppied
这是因为
char **newlines= (char**)realloc(lines , array_size * sizeof(char*));
你不能在 realloc 之后使用 lines 因为 if 可能被 realloc 释放,显然这就是发生的事情,因为 gdb 发出了问题信号
但是你的代码有更多问题
1) 编译器在行 temp[strlen(temp)-1]="[=22=]" ;
上发出错误信号,因为 temp 是 char 的数组,而不是char* 数组,你当然想要 temp[strlen(temp)-1] = 0 ;
2) 在 main 中:
if (words==NULL) printf ("cant build structure");
for (int i=0 ; i<100 ; i++) printf("%s \n" , words[i] );
an else 丢失,如果 worlds 是 NULL 你做 for 和(尝试)以未定义的行为访问 words[i]
3) 在主要
for (int i=0 ; i<100 ; i++) printf("%s \n" , words[i] );
您可以访问 words 的前 100 个条目来打印它们,而不知道它有 size/how 个条目,如果它有少于 100 个条目,您有另一个未定义的行为,如果它有更多你不打印所有这些
loadfile 必须 return 条目数,例如通过输出变量 char **loadfile(size_t * n)
允许您执行 for (int i=0 ; i<n ; i++) ...
4) 在 loadfile
fpointer = fopen ("word.txt" , "r");
if (fpointer==NULL) printf ("file not loaded \n");
else printf ("File loaded \n");
如果你不能打开文件文件你打印一条信息然后你继续执行,你需要return NULL;
请注意,您也很乐观,因为您在打开文件时已经打印了 File loaded
5) 在 loadfile
char ** lines=(char **)malloc(array_size*sizeof(char*));
if (lines=NULL) printf ("cant allocate memory \n");
if malloc returns NULL 打印消息 然后继续执行,所以你可以稍后做 lines[i]=string_coppied;
而 lines 是 NULL 具有未定义的行为
6) 在 loadfile
正如我所说
char **newlines= (char**)realloc(lines , array_size * sizeof(char*));
if (newlines==NULL) //check if the memory was allocated
{
printf ("Cant reallocate memory , please try again \n ");
return 0 ;
}
lines=newlines;
可以替换为
lines= (char**)realloc(lines , array_size * sizeof(char*));
if (lines==NULL) //check if the memory was allocated
{
printf ("Cant reallocate memory , please try again \n ");
return NULL;
}
7) 在 loadfile
做的时候(我把“\0”改成了0):
temp[strlen(temp)-1]=0;
int length =strlen(temp);
你计算字符串长度的 2 倍,而你知道第二个 strlen 值第一个减 1,do
int length = strlen(temp) - 1;
temp[length] = 0;
但是还有一个问题,你这样做是为了去掉换行符,但是
- 文件的最后一行可能不包含换行符,在这种情况下您丢失了最后一个字符。
- 当一行超过 100 个字符时,它会被分成几行,并且第一行不包含换行符并且您删除它们的最后一个字符
为了不剪切行,也不必复制它们,您可以使用 getline
8) 在 loadfile
在
return lines;
free(lines);
fclose(fpointer);
最后两行无法执行,因此您不释放 行(但这样更好,因为您 return 它)并且文件未关闭
提议:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
const int step=200;
char **loadfile(ssize_t * n);
int main()
{
ssize_t n;
char **words=loadfile(&n);
if (words == NULL)
puts("error when reading file");
else {
for (ssize_t i = 0 ; i < n ; i++) {
puts(words[i]);
free(words[i]);
}
}
}
char **loadfile(ssize_t * n)
{
*n = 0;
//We load our text file at the stack
FILE * fpointer = fopen ("word.txt" , "r");
if (fpointer==NULL) {
printf ("file not loaded \n");
return NULL;
}
puts ("load file");
int array_size = 0;
char ** lines = NULL;
for (;;) {
char * lineptr = NULL;
size_t zero = 0;
ssize_t sz = getline(&lineptr, &zero, fpointer);
if (sz <= 0) {
fclose(fpointer);
return lines;
}
if (lineptr[sz - 1] == '\n')
lineptr[sz - 1] = 0;
if (*n == array_size)
{
array_size += step;
lines = realloc(lines , array_size * sizeof(char*));
if (lines == NULL) //check if the memory was allocated
{
printf ("Cant reallocate memory , please try again \n ");
return NULL;
}
}
lines[*n] = lineptr;
*n += 1;
}
}
嘿,我需要一些帮助,我正在尝试在我的 C 程序中加载字典,但出现了段错误。我会喜欢一些帮助。
在使用 gdb 进行调试时,它表示它在第 63 行失败,该命令显示:lines[i]=string_coppied
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
const int step=200;
char **loadfile();
int main()
{
char **words=loadfile();
if (words==NULL) printf ("cant build structure");
for (int i=0 ; i<100 ; i++) printf("%s \n" , words[i] );
}
char **loadfile()
{
//We load our text file at the stack
FILE * fpointer;
fpointer = fopen ("word.txt" , "r");
if (fpointer==NULL) printf ("file not loaded \n");
else printf ("File loaded \n");
int array_size=step;
char ** lines=(char **)malloc(array_size*sizeof(char*));
if (lines=NULL) printf ("cant allocate memory \n");
char temp[100];
int i=0;
while (fgets(temp,100,fpointer))
{
//we check if the already allocated memory is full , if so we realloc
if (i==array_size)
{
array_size +=step;
char **newlines= (char**)realloc(lines , array_size * sizeof(char*));
if (newlines==NULL) //check if the memory was allocated
{
printf ("Cant reallocate memory , please try again \n ");
return 0 ;
}
lines=newlines;
}
//now that we made sure that the memory was allocated we continue by copying the temp //
temp[strlen(temp)-1]="[=10=]" ;
int length =strlen(temp);
char * string_coppied=malloc((length+1) * sizeof(char));
strcpy(string_coppied ,temp);
lines[i]=string_coppied;
i++;
}
return lines;
free(lines);
fclose(fpointer);
}
gdb it says that it failed on line 63 which the command says :
lines[i]=string_coppied
这是因为
char **newlines= (char**)realloc(lines , array_size * sizeof(char*));
你不能在 realloc 之后使用 lines 因为 if 可能被 realloc 释放,显然这就是发生的事情,因为 gdb 发出了问题信号
但是你的代码有更多问题
1) 编译器在行 temp[strlen(temp)-1]="[=22=]" ;
上发出错误信号,因为 temp 是 char 的数组,而不是char* 数组,你当然想要 temp[strlen(temp)-1] = 0 ;
2) 在 main 中:
if (words==NULL) printf ("cant build structure"); for (int i=0 ; i<100 ; i++) printf("%s \n" , words[i] );
an else 丢失,如果 worlds 是 NULL 你做 for 和(尝试)以未定义的行为访问 words[i]
3) 在主要
for (int i=0 ; i<100 ; i++) printf("%s \n" , words[i] );
您可以访问 words 的前 100 个条目来打印它们,而不知道它有 size/how 个条目,如果它有少于 100 个条目,您有另一个未定义的行为,如果它有更多你不打印所有这些
loadfile 必须 return 条目数,例如通过输出变量 char **loadfile(size_t * n)
允许您执行 for (int i=0 ; i<n ; i++) ...
4) 在 loadfile
fpointer = fopen ("word.txt" , "r"); if (fpointer==NULL) printf ("file not loaded \n"); else printf ("File loaded \n");
如果你不能打开文件文件你打印一条信息然后你继续执行,你需要return NULL;
请注意,您也很乐观,因为您在打开文件时已经打印了 File loaded
5) 在 loadfile
char ** lines=(char **)malloc(array_size*sizeof(char*)); if (lines=NULL) printf ("cant allocate memory \n");
if malloc returns NULL 打印消息 然后继续执行,所以你可以稍后做 lines[i]=string_coppied;
而 lines 是 NULL 具有未定义的行为
6) 在 loadfile
正如我所说
char **newlines= (char**)realloc(lines , array_size * sizeof(char*)); if (newlines==NULL) //check if the memory was allocated { printf ("Cant reallocate memory , please try again \n "); return 0 ; } lines=newlines;
可以替换为
lines= (char**)realloc(lines , array_size * sizeof(char*));
if (lines==NULL) //check if the memory was allocated
{
printf ("Cant reallocate memory , please try again \n ");
return NULL;
}
7) 在 loadfile
做的时候(我把“\0”改成了0):
temp[strlen(temp)-1]=0; int length =strlen(temp);
你计算字符串长度的 2 倍,而你知道第二个 strlen 值第一个减 1,do
int length = strlen(temp) - 1;
temp[length] = 0;
但是还有一个问题,你这样做是为了去掉换行符,但是
- 文件的最后一行可能不包含换行符,在这种情况下您丢失了最后一个字符。
- 当一行超过 100 个字符时,它会被分成几行,并且第一行不包含换行符并且您删除它们的最后一个字符
为了不剪切行,也不必复制它们,您可以使用 getline
8) 在 loadfile
在
return lines; free(lines); fclose(fpointer);
最后两行无法执行,因此您不释放 行(但这样更好,因为您 return 它)并且文件未关闭
提议:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
const int step=200;
char **loadfile(ssize_t * n);
int main()
{
ssize_t n;
char **words=loadfile(&n);
if (words == NULL)
puts("error when reading file");
else {
for (ssize_t i = 0 ; i < n ; i++) {
puts(words[i]);
free(words[i]);
}
}
}
char **loadfile(ssize_t * n)
{
*n = 0;
//We load our text file at the stack
FILE * fpointer = fopen ("word.txt" , "r");
if (fpointer==NULL) {
printf ("file not loaded \n");
return NULL;
}
puts ("load file");
int array_size = 0;
char ** lines = NULL;
for (;;) {
char * lineptr = NULL;
size_t zero = 0;
ssize_t sz = getline(&lineptr, &zero, fpointer);
if (sz <= 0) {
fclose(fpointer);
return lines;
}
if (lineptr[sz - 1] == '\n')
lineptr[sz - 1] = 0;
if (*n == array_size)
{
array_size += step;
lines = realloc(lines , array_size * sizeof(char*));
if (lines == NULL) //check if the memory was allocated
{
printf ("Cant reallocate memory , please try again \n ");
return NULL;
}
}
lines[*n] = lineptr;
*n += 1;
}
}