【问题标题】:reading from a file - Segmentation fault (core dumped) [closed]从文件中读取 - 分段错误(核心转储)[关闭]
【发布时间】:2015-12-21 16:29:03
【问题描述】:

我对这个错误有很大的疑问。我尝试了所有我知道的从文件中读取的方法(fscanf、fgets、gets、fgetln、fread、read),但我无法管理它。每次我得到分段错误(核心转储)错误)。我需要做什么才能打印我的文件内容。

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

【问题讨论】:

  • 如果您在崩溃后在 gdb 中执行 bt,您会看到它到底在哪里破坏了它的负载。可能会让你更接近根本原因。一般也可以打开.core文件。

标签: c linux unix segmentation-fault


【解决方案1】:

这些行

char *file_name;

// ...

gets(file_name);

尝试使用未初始化的指针读取数据,这可能会导致在您按下 Enter 键时,甚至在您尝试打开文件之前,将键盘读取到未定义的缓冲区中的段错误。此外,不推荐使用gets()。奇怪的是,你确实知道fgets() 和后面的newline

【讨论】:

    【解决方案2】:

    只需导入打开。如果您使用“with open __”,那么您可以读取该文件。取决于您要使用的读取类型。对于二进制,您可以使用“rb”,但“r”也可以。实际上默认是“wb”。

    【讨论】:

      【解决方案3】:

      您可以使用 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”命令没有参数时才会发生此错误。

      antoine@shell >>
      antoine@shell >>
      antoine@shell >>uniq stack.c
      antoine@shell >>uniq
      [1]    4154 segmentation fault (core dumped)  ./a.out
      

      因为在这种情况下 param[1] 未初始化:

          if(!strcmp(params[1],"-d"))
      

      一种解决方案是让您的 parseCmd 返回检测到的参数数量并检查结果是否为 == 2 (uniq myFile)。

      【讨论】:

        猜你喜欢
        • 2016-02-25
        • 1970-01-01
        • 1970-01-01
        • 2012-10-12
        • 2013-04-28
        • 1970-01-01
        • 2018-12-09
        • 1970-01-01
        • 2012-11-20
        相关资源
        最近更新 更多