从文件读取到字符串数组,C
我试图编写一个函数,使用fgets()将文件中的字符串读取到字符串数组中,但在运行时我不断得到从文件读取到字符串数组,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
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
将与posixread
功能冲突
在下列情况下,程序将失败:
如果文件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)++;
}