Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C中处理POSIX-错误消息:分段错误(内核转储)_C_Regex_Unix_Terminal_Posix - Fatal编程技术网

在C中处理POSIX-错误消息:分段错误(内核转储)

在C中处理POSIX-错误消息:分段错误(内核转储),c,regex,unix,terminal,posix,C,Regex,Unix,Terminal,Posix,我是C编程新手,我被指派在UNIX中创建使用终端的命令行方法。到目前为止,我已经实现了读取文件并以相反顺序读取的方法。最后一部分需要指定行号并显示它(例如:./showfile-l(2)textfile) 我关心的是识别输入,我决定使用正则表达式来完成这项任务,但我似乎找不到一种方法来识别argv[1]中的模式-l(I) 编辑:我所做的一切: void reversetext(FILE * f); void main(int argc, char * argv[]) { regex_t

我是C编程新手,我被指派在UNIX中创建使用终端的命令行方法。到目前为止,我已经实现了读取文件并以相反顺序读取的方法。最后一部分需要指定行号并显示它(例如:./showfile-l(2)textfile)

我关心的是识别输入,我决定使用正则表达式来完成这项任务,但我似乎找不到一种方法来识别argv[1]中的模式-l(I)

编辑:我所做的一切:

void reversetext(FILE * f);
void main(int argc, char * argv[]) {
    regex_t regex;
    int i;
    FILE * f;
    char c;

    if (regcomp( & regex, "-l[[digit:]]+", 0)) {
        printf("Could not compile\n");
        return;
    }

    if (strcmp(argv[1], "-r") == 0) {
        f = fopen(argv[2], "r");
        reversetext(f);
    } else if (regexec( & regex, argv[1], 0, NULL, 0) == 0) {
        printf("%s", argv[1]);
    } else {
        f = fopen(argv[1], "r");
        c = getc(f);

        while (c != EOF) {
            printf("%c", c);
            c = getc(f);
        }
    }

    fclose(f);
}

void reversetext(FILE * f) {
    char c = getc(f);
    if (c == EOF) {
        return;
    }

    reversetext(f);
    printf("%c", c);
}
为什么会出现分段错误?我读过一些以前的帖子,但是没有一个用户在POSIX中遇到这个错误

注意:我已经包含了我需要的库,在main上面

代码说明: ./showfile-r text.txt>>反向查看

第二个if语句指定行

其他:正常打印。

这适用于您:

#define _POSIX_C_SOURCE 200809L

#include <stdio.h>
#include <stdlib.h>
#include <regex.h>

int main(void) {
    const char tests[2][4] = {"-l4", "-lm"};
    const char match[] = "-l[[:digit:]]+";
    regex_t rmatch;

    if ( regcomp(&rmatch, match, REG_EXTENDED) != 0 ) {
        perror("Error compiling regex");
        return EXIT_FAILURE;
    }

    for ( int i = 0; i < 2; ++i ) {
        if ( regexec(&rmatch, tests[i], 0, NULL, 0) != 0 ) {
            printf("No match for '%s'.\n", tests[i]);
        } else {
            printf("Matched '%s'.\n", tests[i]);
        }
    }

    return 0;
}
编辑:在您发布的代码中,您遇到了几个问题:

  • 这一行:

    if(regcomp(&regex,"-l[[digit:]]+",0)){
    
    应该是:

    if( regcomp(&regex, "-l[[:digit:]]+", REG_EXTENDED) ) {
    
    因为您使用的是扩展正则表达式。如果更改此行,您的模式将成功匹配

  • 您的分段错误实际上与您的正则表达式无关,它来自以下调用:

    fclose(f);
    
    当处于从未成功打开文件的执行路径上时。您应该更改:

    FILE *f;
    
    致:

    和变化:

    fclose(f);
    
    致:

    让你自己熟悉gdb将有助于你自己追踪这些事情

  • 以下是您自己的代码的修改版本,可以正常工作,并包括一些基本的错误检查:

    #define _POSIX_C_SOURCE 200809L
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <regex.h>
    
    void reversetext(FILE * f);
    
    int main(int argc, char *argv[]) {
        regex_t rmatch;
        FILE *f = NULL;
        int c;
    
        if ( argc < 2 ) {
            printf("You need to enter at least one command line argument.\n");
            return EXIT_FAILURE;
        }
    
        if ( regcomp(&rmatch, "-l[[:digit:]]+", REG_EXTENDED) ) {
            printf("Could not compile regex.\n");
            return EXIT_FAILURE;
        }
    
        if ( strcmp(argv[1], "-r") == 0 && argc > 2 ) {
            printf("argv[1] is -r\n");
            if ( (f = fopen(argv[2], "r")) == NULL ) {
                fprintf(stderr, "Couldn't open file %s\n", argv[2]);
                return EXIT_FAILURE;
            }
            reversetext(f);
        } else if (regexec(&rmatch, argv[1], 0, NULL, 0) == 0) {
            printf("Matched '%s' to regex\n", argv[1]);
        } else {
            if ( (f = fopen(argv[1], "r")) == NULL ) {
                fprintf(stderr, "Couldn't open file %s\n", argv[1]);
                return EXIT_FAILURE;
            }
    
            while ( (c = getc(f)) != EOF) {
                printf("%c", c);
            }
        }
    
        if ( f ) {
            fclose(f);
        }    
    }
    
    void reversetext(FILE * f) {
        int c = getc(f);
        if (c == EOF) {
            return;
        }
    
        reversetext(f);
        printf("%c", c);
    }
    
    请注意,当您使用
    getc()
    和friends时,他们使用的是
    int
    s,而不是
    char
    s。这是存储
    EOF
    所必需的

    编辑2:根据评论中的问题,您需要做四件事来匹配子组,在本例中,匹配的数字部分

  • 设置类型为
    regmatch\u t
    的数组。您至少需要两个元素,因为第一个元素将匹配整个正则表达式,而一个子组至少需要一秒钟。在下面的代码中,我添加了:

    #define MAX_MATCHES 10
    regmatch_t m_group[MAX_MATCHES];
    
  • 在要提取的正则表达式部分周围加上括号。在下面的代码中,我已更改:

    "-l[[:digit:]]+"
    
    } else if (regexec(&rmatch, argv[1], 0, NULL, 0) == 0) {
    
    致:

  • 调用时将
    regmatch\u t
    数组连同大小一起传递给
    regexec()
    。在下面的代码中,我已更改:

    "-l[[:digit:]]+"
    
    } else if (regexec(&rmatch, argv[1], 0, NULL, 0) == 0) {
    
    致:

  • 在阵列中循环并处理每个匹配项。每当
    regmatch\u t
    数组元素的
    rm\u so
    成员不是
    -1
    时,就有一个匹配项。我在这里所做的就是将它们复制到缓冲区并打印出来:

    } else if ( regexec(&rmatch, argv[1], MAX_MATCHES, m_group, 0) == 0 ) {
        printf("Matched '%s' to regex\n", argv[1]);
        for ( int i = 0; i < MAX_MATCHES && m_group[i].rm_so != -1; ++i ) {
            char buffer[1000] = {0};
            char * match_start = &argv[1][m_group[i].rm_so];
            size_t match_size = m_group[i].rm_eo - m_group[i].rm_so;
            size_t match_len = match_size > 999 ? 999 : match_size;
            strncpy(buffer, match_start, match_len);
            printf("Matched group %d was '%s'\n", i, buffer);
        }
    } 
    

    如果您需要模式方面的帮助,这可能会有所帮助:

    但是关于分割错误,需要更多的细节

    这也是一个工作示例,您只需替换模式:

    发布一个简短的、可编译的示例,其中包含一个
    main()
    函数和一个初始化的缓冲区,而不是
    argv[1]
    ,这样我们就可以试一下了。@PaulGriffiths为什么我要使用缓冲区呢?我的代码需要argv[1],在这种情况下,我不知道在哪里使用我的缓冲区。为了询问您的问题,因为它消除了您无法正确调用程序的可能性,并帮助我们准确查看您传递给
    regexec()
    的内容。也就是说,请参阅我的答案,以了解您问题的解决方案。如果您注意到我发布的代码,这与我正在做的相同,但我放置的不是测试[I],而是argv[1],它应该是-l(I),但没有打印出任何内容..而不是error@Atieh:不一样-您没有将
    REG_EXTENDED
    传递到
    regcomp()
    在您发布的代码中。它起作用了!非常感谢你!在过去的5个小时里,我一直在研究这个问题。请允许我继续完成这个任务:)@Atieh:没问题。我在我的编辑中发布了你的代码的工作版本,以及一些适当的错误检查。顺便问一下,你知道如何提取2 in-l2的例子吗?2将指定行号。
    "-l([[:digit:]]+)"
    
    } else if (regexec(&rmatch, argv[1], 0, NULL, 0) == 0) {
    
    } else if (regexec(&rmatch, argv[1], MAX_MATCHES, m_group, 0) == 0) {
    
    } else if ( regexec(&rmatch, argv[1], MAX_MATCHES, m_group, 0) == 0 ) {
        printf("Matched '%s' to regex\n", argv[1]);
        for ( int i = 0; i < MAX_MATCHES && m_group[i].rm_so != -1; ++i ) {
            char buffer[1000] = {0};
            char * match_start = &argv[1][m_group[i].rm_so];
            size_t match_size = m_group[i].rm_eo - m_group[i].rm_so;
            size_t match_len = match_size > 999 ? 999 : match_size;
            strncpy(buffer, match_start, match_len);
            printf("Matched group %d was '%s'\n", i, buffer);
        }
    } 
    
    #define _POSIX_C_SOURCE 200809L
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <regex.h>
    
    #define MAX_MATCHES 10
    
    void reversetext(FILE * f);
    
    int main(int argc, char *argv[]) {
        regex_t rmatch;
        regmatch_t m_group[MAX_MATCHES];
        FILE *f = NULL;
        int c;
    
        if ( argc < 2 ) {
            printf("You need to enter at least one command line argument.\n");
            return EXIT_FAILURE;
        }
    
        if ( regcomp(&rmatch, "-l([[:digit:]])+", REG_EXTENDED) ) {
            printf("Could not compile regex.\n");
            return EXIT_FAILURE;
        }
    
        if ( strcmp(argv[1], "-r") == 0 && argc > 2) {
            printf("argv[1] is -r\n");
            if ( (f = fopen(argv[2], "r")) == NULL ) {
                fprintf(stderr, "Couldn't open file %s\n", argv[2]);
                return EXIT_FAILURE;
            }
            reversetext(f);
        } else if ( regexec(&rmatch, argv[1], MAX_MATCHES, m_group, 0) == 0 ) {
            printf("Matched '%s' to regex\n", argv[1]);
            for ( int i = 0; i < MAX_MATCHES && m_group[i].rm_so && ; ++i ) {
                char buffer[1000] = {0};
                char * match_start = &argv[1][m_group[i].rm_so];
                size_t match_size = m_group[i].rm_eo - m_group[i].rm_so;
                size_t match_len = match_size > 999 ? 999 : match_size;
                strncpy(buffer, match_start, match_len);
                printf("Matched group %d was '%s'\n", i, buffer);
            }
        }  else {
            if ( (f = fopen(argv[1], "r")) == NULL ) {
                fprintf(stderr, "Couldn't open file %s\n", argv[1]);
                return EXIT_FAILURE;
            }
    
            while ( (c = getc(f)) != EOF) {
                printf("%c", c);
            }
        }
    
        if ( f ) {
            fclose(f);
        }
    }
    
    void reversetext(FILE * f) {
        int c = getc(f);
        if (c == EOF) {
            return;
        }
    
        reversetext(f);
        printf("%c", c);
    }
    
    paul@local:~/src/c/scratch$ ./regex2 -l4
    Matched '-l4' to regex
    Matched group 0 was '-l4'
    Matched group 1 was '4'
    paul@local:~/src/c/scratch$