简单程序分段故障

时间:2012-09-25 02:08:46

标签: c pointers segmentation-fault

我是C的新手,我一直在努力找出指针。

这个程序在几行之后使用-i但是段错误,并且-f segfaults立即使用。

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

void search_and_print ( char pattern[], FILE* search_file );

int main ( int argc, char *argv[] ) {
        const char TOO_MANY_VARIABLES[] = "Too many arguments from the command line!";
        const char NOT_ENOUGH_VARIABLES[] = "\nUSAGE: a.out [-i] [-f filename] (Search Pattern)\n";

        if (argc < 2) { printf(NOT_ENOUGH_VARIABLES); return(1);}
        // If input
        if (strcmp(argv[1],"-i") == 0) {
                char *pattern = argv[2];
                search_and_print(pattern, stdin);
        }


        // If file
        if (strcmp(argv[1],"-f") == 0) {
                char *pattern = argv[3];
                // Check if file exists
                // Open file
                FILE *file = fopen( argv[2], "r" );
                search_and_print(pattern, file);
                fclose( file );
        }

}

void search_and_print ( char pattern[], FILE* search_file ) {
        // Read through file
        const int MAX_CHARACTERS_PER_LINE = 1000;
        char* line[MAX_CHARACTERS_PER_LINE];
        while  ( fgets(*line, MAX_CHARACTERS_PER_LINE, search_file) != NULL )
                if  ( strstr(*line, pattern) != NULL )
                    printf(*line);
}

3 个答案:

答案 0 :(得分:2)

你这里有很多错误。

char* line[MAX_CHARACTERS_PER_LINE];

定义了一个包含1000个指针的数组,而不是字符。 fgets(*line, ...将未初始化的第一个指针传递给fgets,最有可能导致segvio。

printf(*line);

printf的第一个参数是一种格式。永远不要将用户输入作为格式传递,因为这会在您的程序中打开一个巨大的安全漏洞......请参阅http://en.wikipedia.org/wiki/Uncontrolled_format_string

您应该使用fputs(line)printf("%s", line)(一旦修复了行声明)。

int main

您不会返回一个值(错误情况除外)......导致未定义的行为。

FILE *file = fopen( argv[2], "r" );

你应该检查一下是否成功。如果无法打开文件(例如,它不存在),则将其传递给fgets会导致未定义的行为。

if (argc < 2) { printf(NOT_ENOUGH_VARIABLES); return(1);}

此测试对于您的-f情况是不够的。

答案 1 :(得分:0)

对于任何人的未来参考,以下是具有建议更改的代码,似乎有效。再次感谢您的帮助!

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

void search_and_print ( char pattern[], FILE* search_file );
int usage(const char* err);

const char USAGE[] =
                "\nUSAGE: a.out [-i] [-f filename] (Search Pattern)";

int main ( int argc, char *argv[] ) {
        const char TOO_MANY_VARIABLES[] = "Too many arguments from the command line!";


        if (argc < 2) return usage("Not enough options");
        if (argc > 4) return usage("Too many arguments from the command line!");

        // If input
        if (strcmp(argv[1],"-i") == 0) {
                if (argc > 2) {
                        char *pattern = argv[2];
                        search_and_print(pattern, stdin);
                }
                else {
                        printf("Need a pattern to search by!");
                        return 1;
                }
        }

        // If file
        if (strcmp(argv[1],"-f") == 0) {
                if (argc > 3)   {
                        char *pattern = argv[3];
                        // Open file
                        FILE *file = fopen( argv[2], "r" );
                        // Check if file exists
                        if ( file != NULL) {
                                search_and_print(pattern, file);
                                fclose( file );
                        } else {
                                printf("File not found!");
                                return 1;
                        }
                } else {
                        printf("Need a pattern to search by!");
                        return 1;
                }
        }
        return 0;
}

int usage(const char* err) {
        fprintf(stderr, "%s\n%s\n", err, USAGE);
        return 1;
}

void search_and_print ( char pattern[], FILE* search_file ) {
        const int MAX_CHARACTERS_PER_LINE = 1000;
        char line[MAX_CHARACTERS_PER_LINE];
        // Read through file
        while  ( fgets(line, MAX_CHARACTERS_PER_LINE, search_file) != NULL )
                if  ( strstr(line, pattern) != NULL )
                    printf("%s", line);
}

答案 2 :(得分:0)

你不需要

char* line[MAX_CHARACTERS_PER_LINE]; 

这是一个指向数组的指针(如果你想逐行存储文件或输入,可能很有用)并且你还没有先分配它。因此seg故障非常明显。

将search_and_print更改为:

void search_and_print ( char pattern[], FILE* search_file ) {
        // Read through file
        const int MAX_CHARACTERS_PER_LINE = 1000;
        char line[MAX_CHARACTERS_PER_LINE];
        while  ( fgets(line, MAX_CHARACTERS_PER_LINE, search_file) != NULL )
                if  ( strstr(line, pattern) != NULL )
                    printf("%s\n", line);
}

除了Jim Balter非常好的建议之外,我还建议使用getopt来解析你的参数。