如何在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=]" ; 上发出错误信号,因为 tempchar 的数组,而不是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 丢失,如果 worldsNULL 你做 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;linesNULL 具有未定义的行为

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;
  }
}