我正在写一个Vanilla文件读取代码。
大部分都是这样的。
首先是头文件file.h
// fheader.h
#ifndef __file_h__
#define __file_h__
// start from here
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void readFile(FILE *fr);
FILE* openFile(char *file_name);
#endif
主文件fmain.c
#include "fheader.h"
void readFile(FILE *fr) {
// Added Printf
printf("\n...\n");
printf("\n...\n");
printf("\n...\n");
printf("\n...\n");
char *buffer = calloc(sizeof(char),1);
while(!feof(fr)) {
fread(buffer,sizeof(char),1,fr);
printf("%s\n",buffer);
}
free(buffer);
return;
}
FILE* openFile(char *file_name) {
// printf("the file name that is going to be opened is %s",file_name);
FILE *fr;
fr = fopen(file_name,"r");
return fr;
}
int main(int argc,char *argv[]) {
if(argc < 2) {
printf("USAGE: ./file test.txt\n");
return 1;
}
if (argc > 2) {
printf("ERROR: Too many argument\n");
return 1;
}
FILE *fr;
char *file_name = calloc(strlen(argv[1]),sizeof(char));
strncpy(file_name,argv[1],strlen(argv[1]));
fr = openFile(file_name);
printf("\nReading from file\n");
readFile(fr);
fclose(fr);
free(file_name);
return 0;
}
我使用以下命令编译代码
gcc -g3 -Wall fmain.c -o file.o
当我运行代码时
./file.o "~/workspaces/myWork/C_experiment/test.txt"
我看到Segmentation fault: 11
但是当我在lldb中运行上面的程序时,我工作并退回并返回代码0
lldb ./file.o
(lldb) run "~/workspaces/myWork/C_experiment/test.txt"
// output of the file
Process 28806 exited with status = 0 (0x00000000)
(lldb) quit
现在,我对如何调试代码并找到Seg Fault原因一无所知。
答案 0 :(得分:0)
您忘记在file_name的末尾添加'\ 0',当您执行fread读取1个字符时,您不会在缓冲区的末尾添加'\ 0'。 如果您只读取一个字符,则应使用char而不是1的数组。
错误在这里:
char *file_name = calloc(strlen(argv[1]),sizeof(char));
strncpy(file_name,argv[1],strlen(argv[1]));
fr = openFile(file_name);
您复制了argv [1],但最后没有添加'\ 0'。那么fopen将如何知道你的字符串停止在哪里? 你应该为calloc添加一个+1,在strncpy之后,你应该像这样添加'\ 0':
file_name[strlen(argv[1])] = '\0';
第二个错误在这里:
char *buffer = calloc(sizeof(char),1);
while(!feof(fr)) {
fread(buffer,sizeof(char),1,fr);
printf("%s\n",buffer);
}
您为缓冲区分配1并读取1,这没关系,但是当您将它发送到printf时,您没有在缓冲区中添加'\ 0',那么printf如何知道停止的位置?
你应该calloc 2而不是一个,然后添加一个buffer[1] = '\0';
所以使用这些修复:
#include "fheader.h"
void readFile(FILE *fr) {
char buffer;
while(!feof(fr)) {
fread(&buffer,sizeof(char),1,fr);
printf("%c\n",buffer);
}
return;
}
FILE* openFile(char *file_name) {
// printf("the file name that is going to be opened is %s",file_name);
FILE *fr;
fr = fopen(file_name,"r");
return fr;
}
int main(int argc,char *argv[]) {
if(argc < 2) {
printf("USAGE: ./file test.txt\n");
return 1;
}
if (argc > 2) {
printf("ERROR: Too many argument\n");
return 1;
}
FILE * fr = openFile(argv[1]);
printf("\nReading from file\n");
readFile(fr);
fclose(fr);
return 0;
}