从文件读取到字符串数组,C

从文件读取到字符串数组,C,c,C,我试图编写一个函数,使用fgets()将文件中的字符串读取到字符串数组中,但在运行时我不断得到zsh:segmentation fault 这是我的密码: #include <stdio.h> #include <stdlib.h> #include <string.h> void read(FILE*, char[][31],int*,int); void printAll(char[][31],int*); int main(int argc, cha

我试图编写一个函数,使用fgets()将文件中的字符串读取到字符串数组中,但在运行时我不断得到
zsh:segmentation fault

这是我的密码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void read(FILE*, char[][31],int*,int);
void printAll(char[][31],int*);

int main(int argc, char** argv) {


    FILE *in = fopen("strings.dat", "r");
    char strarr[50][31];
    int items=0;

    read(in,strarr,&items,31);
    printAll(strarr,&items);

}

void read(FILE *in,char arr[][31],int *items,int len){
    int i = 0;
    char temp[31];
    while (fgets(temp, len, in) != NULL) {
        strcpy(arr[i], temp);
        i++;
        items++;
    }
}
void printAll(char arr[][31],int *items){
    for(int i = 0;i<*items;i++){
        printf("String %d: %s\n",i+1,arr[i]);
    }
}
#包括
#包括
#包括
无效读取(文件*,字符[][31],整数*,整数);
void printAll(char[][31],int*);
int main(int argc,字符**argv){
FILE*in=fopen(“strings.dat”,“r”);
char strarr[50][31];
整数项=0;
读取(in、strarr和items,31);
打印所有(strarr和项目);
}
无效读取(文件*in,字符arr[][31],整数*项,整数len){
int i=0;
字符温度[31];
while(fgets(温度、长度、英寸)!=NULL){
strcpy(arr[i],温度);
i++;
项目++;
}
}
void printAll(字符arr[][31],int*项){

对于(inti=0;i,您的代码几乎是正确的

错误:

  • read
    函数中
    items++
    是错误的,这会增加指针,但您希望增加指针指向的变量,因此您需要
    (*items)+

  • 根据平台的不同,
    read
    将与posix
    read
    功能冲突


  • 在下列情况下,程序将失败:

  • 如果文件
    strings.dat
    不存在,
  • 中的
    将为
    NULL
    ,并且对NULL
    文件
    指针执行文件操作会导致未定义的行为,这通常表现为seg故障。这可能就是您的情况

  • 如果文件包含超过50行,则会溢出
    strarr
    ,这也会导致未定义的行为

  • 如果文件中的行超过31个字符,则行将被截断和/或拆分


  • 奖金:

    temp变量不是必需的,您可以直接读取数组:

    与此相反:

     char temp[31];
     while (fgets(temp, len, in) != NULL) {
        strcpy(arr[i], temp);
        ...
    
    您可以选择:

     while (fgets(arr[i], len, in) != NULL) {
        ...
    

    带更正的最终代码:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    void read(FILE*, char[][31], int*, int);
    void printAll(char[][31], int*);
    
    int main(int argc, char** argv) {
      FILE* in = fopen("strings.dat", "r");
      if (in == NULL)
      {
        printf("file does not exist\n");
        exit(1);
      }
      char strarr[50][31];
      int items = 0;
    
      read(in, strarr, &items, 31);
      printAll(strarr, &items);
    
    }
    
    void read(FILE* in, char arr[][31], int* items, int len) {
      int i = 0;
      while (fgets(arr[i], len, in) != NULL) {
        i++;
        (*items)++;
      }
    }
    
    void printAll(char arr[][31], int* items) {
      for (int i = 0; i < *items; i++) {
        printf("String %d: %s\n", i + 1, arr[i]);
      }
    }
    
    甚至更短:

    void read(FILE* in, char arr[][31], int* items, int len) {
      for (int i = 0; fgets(arr[i], len, in) != NULL; i++)
        (*items)++;
    }
    

    您是否使用过
    valgirnd
    或clang/gcc的地址消毒剂?了解
    “strings.dat”
    的内容至关重要:有多少行以及所有行的最大长度。可能与分段错误无关,但您希望
    (*项)+
    在函数中(增加指针本身没有好处或坏处).
    fopen
    可能会失败,而您没有检查。如果
    fopen
    失败并继续,可能会发生各种奇怪的事情,包括POSIX函数中的“分段错误”(由
    fgets
    调用),因此请使用另一个名称,例如
    my_read
    。请阅读。如果使用编译,请使用
    gcc-Wall-Wextra-g
    获取警告和调试信息
    while(fgets(arr[i],len,in)!=NULL)
    对于此语句,我需要增加索引还是自动增加?为什么要自动增加索引?您使用
    i++
    语句正确地增加了索引。我可以使用*项指向存储读取到数组中的字符串数量的数字吗?@AKu是的,这正是您试图做的,但是u编写了
    items++
    而不是
    (*items)+;
    void read(FILE* in, char arr[][31], int* items, int len) {
      for (int i = 0; fgets(arr[i], len, in) != NULL; i++)
        (*items)++;
    }