简体   繁体   English

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

[英]Read from file to array of strings, C

I'm trying to write a function that read string from a file into an array of strings using fgets(), but I keep getting zsh: segmentation fault at runtime.我正在尝试编写一个 function ,它使用 fgets() 将文件中的字符串读取到字符串数组中,但我不断收到zsh: segmentation fault

Here is my code:这是我的代码:

#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]);
    }
}

How can I fix it?我该如何解决?

Your code is almost correct.您的代码几乎是正确的。

Errors:错误:

  1. In the read function items++ is wrong, this increments the pointer but you want to increment the variable pointed by the pointer, therefore you need (*items)++ instead.read function items++是错误的,这会增加指针但您想增加指针指向的变量,因此您需要(*items)++代替。

  2. Depending on the platform read will conflict with the posix read function.根据平台read将与 posix read function 冲突。


The program will fail under following conditions:该程序将在以下情况下失败:

  1. If the file strings.dat does not exist, in will be NULL and doing file operations on a NULL FILE pointer results in undefined behaviour which often manifests in a seg fault.如果文件strings.dat不存在in NULL并对 NULL FILE指针执行文件操作会导致未定义的行为,这通常表现为段错误。 This is probably what happens to you.这可能就是发生在你身上的事情。

  2. If the file contains more than 50 lines you will be overflowing strarr which also results in undefined behaviour如果文件包含超过 50 行,您将溢出strarr这也会导致未定义的行为

  3. If lines in the file have more than 31 characters, lines will be truncated and/or split.如果文件中的行超过 31 个字符,行将被截断和/或拆分。


Bonus:奖金:

The temp variable is not necessary, you can read directly into the array: temp 变量不是必需的,您可以直接读入数组:

Instead of this:而不是这个:

 char temp[31];
 while (fgets(temp, len, in) != NULL) {
    strcpy(arr[i], temp);
    ...

You can have this:你可以有这个:

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

Final code with corrections:带有更正的最终代码:

#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]);
  }
}

Alternative version of read read的替代版本

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

Even shorter:更短:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM