C 读取文件-分段错误(内核转储)
我对这个错误有一个很大的问题。我尝试了所有我知道的方法来读取文件(fscanf、fgets、gets、fgetln、fread、read),但我无法管理它。每次我得到分段错误(核心转储)错误)。打印文件内容需要做什么C 读取文件-分段错误(内核转储),c,linux,unix,segmentation-fault,C,Linux,Unix,Segmentation Fault,我对这个错误有一个很大的问题。我尝试了所有我知道的方法来读取文件(fscanf、fgets、gets、fgetln、fread、read),但我无法管理它。每次我得到分段错误(核心转储)错误)。打印文件内容需要做什么 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <unistd.h> #include <
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <ctype.h>
#include <signal.h>
#include <termios.h>
#include <dirent.h>
#include <err.h>
#include <errno.h>
#define MAX_COMAND_LENGTH 100
#define MAX_NUMBER_OF_PARAMS 10
int i=0;
char cmd[MAX_COMAND_LENGTH+1];
char *params[MAX_NUMBER_OF_PARAMS+1];
char cmdline[1000];
int hfd=-1,ifd=-1,ofd=-1;
int lines_in_hist = 0;
int curent_line = -1;
struct termios save_term;
char *HISTORY;
char *TEMP,*TEMP2,*ax;
void parseCmd(char *cmd, char **params)
{
for(i=0; i< MAX_NUMBER_OF_PARAMS;i++){
params[i]=strsep(&cmd," ");
if(params[i] == NULL)
break;
}
}
int main(int argc, char *argv[])
{
char *username = getenv("USER");
int status=-1;//pentru deschiderea fisierelor
int status1;
char *directory="/tmp";
char *file_name;
char buff[256];
while(1)
{
printf("%s@shell >>", username);
//citeste de pe linia de comanda
if(fgets(cmd,sizeof(cmd),stdin)==NULL)
break;
//elimina terminatorul de sir de pe o linie noua
if(cmd[strlen(cmd)-1]=='\n')
cmd[strlen(cmd)-1]='\0';
parseCmd(cmd,params);
if(!strcmp(params[0],"exit"))
exit(0);
if(!strcmp(params[0],"help"))
help();
if(!strcmp(params[0],"version"))
version();
if(!strcmp(params[0],"info"))
if(!strcmp(params[1],"tail"))
infoTail();
else if(!strcmp(params[1],"uniq"))
infoUniq();
else if(!strcmp(params[1],"cd"))
infoCd();
if(!strcmp(params[0],"uniq"))
{
if(!strcmp(params[1],"-d"))
{
printf("Enter the name of file\n");
gets(file_name);
if((status=open(file_name,O_RDONLY))==-1)
{
printf("Nu am putut deschide fisierul!");
exit(1);
}
else
{
printf("\t\t ==>%s<==\n",file_name);
sscanf(file_name,"%s",buff);
printf("Continutul fisierului:\n%s\n", buff);
}
close(status);
}
}
if(!strcmp(params[0],"cd"))
{
status1=chdir(directory);
if(status1 !=0)
perror("Eroare!");
}
}
return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义最大COMU和长度100
#定义参数10的最大数量
int i=0;
char cmd[最大长度+1];
char*params[最大参数数+1];
char-cmdline[1000];
int hfd=-1,ifd=-1,ofd=-1;
int lines_in_hist=0;
int current_line=-1;
结构术语保存术语;
char*历史;
字符*TEMP,*TEMP2,*ax;
void parseCmd(char*cmd,char**params)
{
对于(i=0;i>”,用户名);
//科曼达城市酒店
如果(fgets(cmd,sizeof(cmd),stdin)=NULL)
打破
//伊莱米娜·终结者德佩奥·利尼·努亚爵士
如果(cmd[strlen(cmd)-1]=='\n')
cmd[strlen(cmd)-1]='\0';
parseCmd(cmd,params);
如果(!strcmp(参数[0],“退出”))
出口(0);
如果(!strcmp(参数[0],“帮助”))
帮助();
如果(!strcmp(参数[0],“版本”))
版本();
如果(!strcmp(参数[0],“信息”))
如果(!strcmp(参数[1],“tail”))
infoTail();
如果(!strcmp(参数[1],“uniq”))
infoUniq();
如果(!strcmp(参数[1],“cd”))
infoCd();
如果(!strcmp(参数[0],“uniq”))
{
如果(!strcmp(参数[1],“-d”))
{
printf(“输入文件名\n”);
获取(文件名);
如果((状态=打开(文件名,仅限))=-1)
{
printf(“nuam putut deschide fisierul!”);
出口(1);
}
其他的
{
printf(“\t\t=>%s只需导入打开。如果使用“with open”\uuuuuuuuuuuuuuuu”,则可以读取文件。具体取决于要使用的读取类型。对于二进制文件,可以使用“rb”,但“r”也可以工作。默认值实际上是“wb”。这些行
char *file_name;
// ...
gets(file_name);
尝试使用未初始化的指针读取数据,这可能会导致在您尝试打开文件之前按Enter键将键盘读入未定义的缓冲区时出现SEGFULT。此外,不推荐使用get()
。奇怪的是,您确实知道fgets()
和尾随的换行符
要查找错误所在,可以使用valgrind:
gcc -g stack.c
valgrind ./a.out
这表明您的程序在第86行出现故障
==3384== Invalid read of size 1
==3384== at 0x4C2F1B1: strcmp (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3384== by 0x400C52: main (stack.c:86)
==3384== Address 0x0 is not stack'd, malloc'd or (recently) free'd
只有当“uniq”命令没有参数时,才会发生此错误
因为在这种情况下,参数[1]未初始化:
if(!strcmp(params[1],"-d"))
解决方案是让parseCmd返回检测到的参数数量,并检查结果是否为==2(uniq myFile)。如果在崩溃后在gdb中执行bt,您将看到其负载的确切位置。这可能使您更接近根本原因。通常还可以打开.core文件。
if(!strcmp(params[1],"-d"))