繁体   English   中英

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

[英]Dealing with POSIX in C - Error message: Segmentation Fault (core dumped)

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

我关心的是确定输入,因此我决定使用Regex来完成此任务,但似乎找不到在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;
}

输出:

paul@local:~/src/c/scratch$ ./regex
Matched '-l4'.
No match for '-lm'.
paul@local:~/src/c/scratch$

编辑:在您发布的代码中,您有几个问题:

  1. 这行:

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

    应该:

     if( regcomp(&regex, "-l[[:digit:]]+", REG_EXTENDED) ) { 

    因为您使用的是扩展的正则表达式。 如果更改此行,则您的模式将成功匹配。

  2. 您的细分错误实际上与您的正则表达式无关,它来自于此调用:

     fclose(f); 

    在从未成功打开文件的执行路径上。 您应该更改:

     FILE *f; 

    至:

     FILE *f = NULL; 

    并更改:

     fclose(f); 

    至:

     if ( 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);
}

输出:

paul@local:~/src/c/scratch$ ./regex2 -l4
Matched '-l4' to regex
paul@local:~/src/c/scratch$ ./regex2 -r fakefile
argv[1] is -r
Couldn't open file fakefile
paul@local:~/src/c/scratch$ ./regex2 -tribbles
Couldn't open file -tribbles
paul@local:~/src/c/scratch$ ./regex2 testfile
This is a test.
paul@local:~/src/c/scratch$ ./regex2 -r testfile
argv[1] is -r

.tset a si sihTpaul@local:~/src/c/scratch$

请注意,当您使用getc()和朋友时,他们使用int而不是char 为了能够存储EOF这是必需的。

编辑2:根据您评论中的问题,您需要做四件事来匹配一个子组,在这种情况下,是匹配的数字部分。

  1. 设置一个类型为regmatch_t的数组。 您将至少需要两个元素,因为第一个元素将匹配整个正则表达式,并且一个子组至少需要第二个元素。 在下面的代码中,我添加了:

     #define MAX_MATCHES 10 regmatch_t m_group[MAX_MATCHES]; 
  2. 将正则表达式要提取的部分放在括号中。 在下面的代码中,我进行了更改:

     "-l[[:digit:]]+" 

    至:

     "-l([[:digit:]]+)" 
  3. 通过您的regmatch_t数组regexec()时,你怎么称呼它,用大小一起。 在下面的代码中,我进行了更改:

     } else if (regexec(&rmatch, argv[1], 0, NULL, 0) == 0) { 

    至:

     } else if (regexec(&rmatch, argv[1], MAX_MATCHES, m_group, 0) == 0) { 
  4. 循环遍历数组并处理每个匹配项。 每次regmatch_t数组元素的rm_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); } } 

这是更新的代码:

#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$

如果您需要模式方面的帮助,则可能会有所帮助: http : //www.cheatography.com/davechild/cheat-sheets/regular-expressions/

但是关于分段错误,需要更多细节。

这也是一个可行的示例,您只需要替换模式即可: C:示例中的正则表达式?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM