C 中的分段错误(核心转储)



该程序基本上在文件中搜索字符串,然后根据提供的选项生成输出。

例如,在命令行上,

Cmatch-我你好你好世界.txt

即使我注释掉了所有 printf 语句,我也不断遇到分段错误。但是我是C的新手,在这里找不到任何不合适的指针。帮助?

#include <errno.h>
#include <libgen.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdbool.h>
int exit_status = EXIT_SUCCESS;
bool checkIfMatch(char *string, FILE *file) {
    while (true) {
        char buff[1024];
        fgets(buff, 1024, file);
        if (buff == NULL)
            break;
        if (strcmp(string, strstr(buff, string)) == 0)
            return true;
    }
    return false;
}

bool checkIfMatchIgnoreCase(char *string, FILE *file){
    while (true) {
        char buff[1024];
        fgets(buff, 1024, file);
        if (buff == NULL)
            break;
        if (strcasecmp(string, strstr(buff, string))== 0)
            return true;
    }
    return false;
}
void printLines(char *string, FILE *file){
    while (true) {
        char buff[1024];
        fgets(buff, 1024, file);
            if (buff == NULL)
                break;
            if (strcmp(string, strstr(buff, string)) == 0)
                printf("%s",buff);
        }
}
void printLinesWithNumber(char *string, FILE *file){
    int ln;
    for(ln=1;;ln++) {
            char buff[1024];
            fgets(buff, 1024, file);
            if (buff == NULL)
                break;
            if (strcmp(string, strstr(buff, string)) == 0)
                printf("%d: %s",ln,buff);
        }
}
typedef struct options {
    bool ignore_case;
    bool filenames_only;
    bool number_lines;
} options;
void scan_options(int argc, char **argv, options *opts) {
    opts->ignore_case = false;
    opts->filenames_only = false;
    opts->number_lines = false;
    opterr = false;
    for (;;) {
        int opt = getopt(argc, argv, "iln");
        if (opt == EOF)
            break;
        switch (opt) {
        case 'i':
            opts->ignore_case = true;
            break;
        case 'l':
            opts->filenames_only = true;
            break;
        case 'n':
            opts->number_lines = true;
            break;
        default:
            exit_status = EXIT_FAILURE;
            fflush(NULL);
           fprintf(stderr, "%s: -%c: invalid optionn", 
                "cmatch.c", optopt);
            break;
        }
    }
}

int main(int argc, char **argv) {
    options opts;
    scan_options(argc, argv, &opts);
    char *stringToMatch = argv[optind];
    int i;
    for(i=1;i<=argc-optind-1;i++){
    bool matched;
    FILE *file=fopen(argv[optind+i],"r");
    if(opts.ignore_case) matched=checkIfMatch(stringToMatch, file);
    else matched=checkIfMatchIgnoreCase(stringToMatch, file);
    if(matched){
        if(opts.filenames_only) printf("%sn",argv[optind+i]);
        if(opts.number_lines) printLinesWithNumber(stringToMatch, file);
        else printLines(stringToMatch,file);
    }
    }
    return exit_status;
}
char *buff = fgets(buff, 1024, file);
      ^^^          ^^^

您需要使用已分配的内存调用fgets。像这样:

char buff[1024];
fgets(buff, sizeof buff, file);

你从不检查fopen()是否真的有效。

FILE *file=fopen(...);
if (NULL != f) {    /* If the file was actually opened */
    /* Do the work */
}

另外,你真的有一个名为 argv[optind+i] 的文件吗?也许你的意思是省略引号:

fopen(argv[optind+i],"r");

此外,看起来您需要在连续调用fgets() http://www.cplusplus.com/reference/cstdio/fseek/之前使用 fseek()rewind()

最后,从文件读取速度很慢。您实际上应该在一个地方读取一次文件,然后重用内存中的内容。

好的,您已经解决了文件问题。现在使用 gdb ,我发现您的第一个分段错误发生在 strcmp() 的第 18 行,因为如果在buff中找不到序列strstr()则返回NULL

    if (strcmp(string, strstr(buff, string)) == 0)
        return true;

您需要将strstr()移出参数以strcmp()并检查NULL,然后再将结果传递给 strcmp() 。 http://www.cplusplus.com/reference/cstring/strstr/

相关内容

  • 没有找到相关文章

最新更新