C 文本文件上的Strtok导致seg故障

C 文本文件上的Strtok导致seg故障,c,file,pointers,segmentation-fault,C,File,Pointers,Segmentation Fault,我有一个文本文件,内容如下: 5f6 2f6 4f6 我想从该文本文件中获取数字(作为字符),然后使用atol() 我有密码: #include <ncurses.h> #include <stdlib.h> #include <string.h> #include <stdio.h> int main(int argc, char * argv[]) { initscr(); cbreak(); noecho();

我有一个文本文件,内容如下:

5f6
2f6
4f6
我想从该文本文件中获取数字(作为字符),然后使用
atol()

我有密码:

#include <ncurses.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

int main(int argc, char * argv[])
{
    initscr();
    cbreak();
    noecho();

    char buf[100];
    char * ptr;
    char * ptr2;
    char * ptr3;
    char * ptr4;
    int a;
    int b;
    int c; 
    int d;

    FILE* file;
    if (strcmp(argv[1],"test.txt") == 0)
    {
        file = fopen("test.txt","r");

        while (fgets(buf,100,file) )

        ptr = strtok(str,"f");
        ptr2 = strtok(NULL," ");
        ptr3 = strtok(NULL,"f");
        ptr4 = strtok(NULL," ");
        a = atol(ptr);
        b = atol(ptr2);
        c = atol(ptr3);
        d = atol(ptr4);
    }

    refresh();
    getchar(); 
    endwin();
    return (0);
}
#包括
#包括
#包括
#包括
int main(int argc,char*argv[])
{
initscr();
cbreak();
noecho();
char-buf[100];
char*ptr;
char*ptr2;
char*ptr3;
char*ptr4;
INTA;
int b;
INTC;
int d;
文件*文件;
if(strcmp(argv[1],“test.txt”)==0)
{
file=fopen(“test.txt”、“r”);
而(fgets(buf,100,文件))
ptr=strtok(str,“f”);
ptr2=strtok(空,“”);
ptr3=strtok(空,“f”);
ptr4=strtok(空,“”);
a=环礁(ptr);
b=环礁(ptr2);
c=环礁(ptr3);
d=环礁(ptr4);
}
刷新();
getchar();
endwin();
返回(0);
}

但是,程序seg会出错,但会编译。我如何才能更有效地执行此操作(通过不出现seg错误的方法)?

您有几个问题

  • 您不检查文件是否已打开

    • fopen()
      之后,必须确保可以从文件中读取,如果
      fopen()
      失败,它将返回
      NULL
      ,因此

      if (file == NULL)
          return -1;
      
    将防止程序的其余部分出现问题

  • 您的
    while
    循环只包含一条语句,因为它缺少大括号

    • 如果没有大括号,while循环相当于

      while (fgets(buf, sizeof(buf), file))
       {
          ptr = strtok(buf, "f");
       }
      
  • 您不会检查
    strtok()
    是否返回了非
    NULL

    • 如果在字符串中找不到令牌,
      strtok()
      返回
      NULL
      ,并且您仍然将返回的指针传递到
      atol

      这将导致未定义的行为,并且可能导致分段错误

  • 您不检查是否有传递给程序的参数,但仍尝试将其与字符串进行比较。还有潜在的未定义行为

  • 我不知道下面的程序是否能满足您的需要,因为它是您自己的程序,我只是让它更安全,避免了未定义的行为

    #include <ncurses.h>
    #include <stdlib.h>
    #include <string.h>
    #include <stdio.h>
    
    int main(int argc, char * argv[])
    {
        char buf[100];
        char *ptr;
        char *ptr2;
        char *ptr3;
        char *ptr4;
        int   a;
        int   b;
        int   c;
        int   d;
        FILE *file;
    
        initscr();
        cbreak();
        noecho();
    
        if (argc > 1)
         {
            file = fopen(argv[1], "r");
            if (file == NULL)
                return -1;
            while (fgets(buf,100,file) != NULL)
             {
                ptr  = strtok(str,"f");
                ptr2 = strtok(NULL," ");
                ptr3 = strtok(NULL,"f");
                ptr4 = strtok(NULL," ");
                if (ptr != NULL)
                    a = atoi(ptr);
                if (ptr2 != NULL)
                    b = atoi(ptr2);
                if (ptr3 != NULL)
                    c = atoi(ptr3);
                if (ptr4 != NULL)
                    d = atoi(ptr4);
             }
         }
        refresh();
        getchar();
        endwin();
    
        return 0;
    }
    
    #包括
    #包括
    #包括
    #包括
    int main(int argc,char*argv[])
    {
    char-buf[100];
    char*ptr;
    char*ptr2;
    char*ptr3;
    char*ptr4;
    INTA;
    int b;
    INTC;
    int d;
    文件*文件;
    initscr();
    cbreak();
    noecho();
    如果(argc>1)
    {
    file=fopen(argv[1],“r”);
    if(file==NULL)
    返回-1;
    while(fgets(buf,100,文件)!=NULL)
    {
    ptr=strtok(str,“f”);
    ptr2=strtok(空,“”);
    ptr3=strtok(空,“f”);
    ptr4=strtok(空,“”);
    如果(ptr!=NULL)
    a=atoi(ptr);
    如果(ptr2!=NULL)
    b=atoi(ptr2);
    如果(ptr3!=NULL)
    c=atoi(ptr3);
    如果(ptr4!=NULL)
    d=atoi(ptr4);
    }
    }
    刷新();
    getchar();
    endwin();
    返回0;
    }
    
    您有几个问题

  • 您不检查文件是否已打开

    • fopen()
      之后,必须确保可以从文件中读取,如果
      fopen()
      失败,它将返回
      NULL
      ,因此

      if (file == NULL)
          return -1;
      
    将防止程序的其余部分出现问题

  • 您的
    while
    循环只包含一条语句,因为它缺少大括号

    • 如果没有大括号,while循环相当于

      while (fgets(buf, sizeof(buf), file))
       {
          ptr = strtok(buf, "f");
       }
      
  • 您不会检查
    strtok()
    是否返回了非
    NULL

    • 如果在字符串中找不到令牌,
      strtok()
      返回
      NULL
      ,并且您仍然将返回的指针传递到
      atol

      这将导致未定义的行为,并且可能导致分段错误

  • 您不检查是否有传递给程序的参数,但仍尝试将其与字符串进行比较。还有潜在的未定义行为

  • 我不知道下面的程序是否能满足您的需要,因为它是您自己的程序,我只是让它更安全,避免了未定义的行为

    #include <ncurses.h>
    #include <stdlib.h>
    #include <string.h>
    #include <stdio.h>
    
    int main(int argc, char * argv[])
    {
        char buf[100];
        char *ptr;
        char *ptr2;
        char *ptr3;
        char *ptr4;
        int   a;
        int   b;
        int   c;
        int   d;
        FILE *file;
    
        initscr();
        cbreak();
        noecho();
    
        if (argc > 1)
         {
            file = fopen(argv[1], "r");
            if (file == NULL)
                return -1;
            while (fgets(buf,100,file) != NULL)
             {
                ptr  = strtok(str,"f");
                ptr2 = strtok(NULL," ");
                ptr3 = strtok(NULL,"f");
                ptr4 = strtok(NULL," ");
                if (ptr != NULL)
                    a = atoi(ptr);
                if (ptr2 != NULL)
                    b = atoi(ptr2);
                if (ptr3 != NULL)
                    c = atoi(ptr3);
                if (ptr4 != NULL)
                    d = atoi(ptr4);
             }
         }
        refresh();
        getchar();
        endwin();
    
        return 0;
    }
    
    #包括
    #包括
    #包括
    #包括
    int main(int argc,char*argv[])
    {
    char-buf[100];
    char*ptr;
    char*ptr2;
    char*ptr3;
    char*ptr4;
    INTA;
    int b;
    INTC;
    int d;
    文件*文件;
    initscr();
    cbreak();
    noecho();
    如果(argc>1)
    {
    file=fopen(argv[1],“r”);
    if(file==NULL)
    返回-1;
    while(fgets(buf,100,文件)!=NULL)
    {
    ptr=strtok(str,“f”);
    ptr2=strtok(空,“”);
    ptr3=strtok(空,“f”);
    ptr4=strtok(空,“”);
    如果(ptr!=NULL)
    a=atoi(ptr);
    如果(ptr2!=NULL)
    b=atoi(ptr2);
    如果(ptr3!=NULL)
    c=atoi(ptr3);
    如果(ptr4!=NULL)
    d=atoi(ptr4);
    }
    }
    刷新();
    getchar();
    endwin();
    返回0;
    }
    
    您有几个问题

  • 您不检查文件是否已打开

    • fopen()
      之后,必须确保可以从文件中读取,如果
      fopen()
      失败,它将返回
      NULL
      ,因此

      if (file == NULL)
          return -1;
      
    将防止程序的其余部分出现问题

  • 您的
    while
    循环只包含一条语句,因为它缺少大括号

    • 如果没有大括号,while循环相当于

      while (fgets(buf, sizeof(buf), file))
       {
          ptr = strtok(buf, "f");
       }
      
  • 您不会检查
    strtok()
    是否返回了非
    NULL

    • 如果在字符串中找不到令牌,
      strtok()
      返回
      NULL
      ,并且您仍然将返回的指针传递到
      atol

      T