0

我是 C 的新手,我一直在试图找出指针。

该程序与 -i 一起使用,但在几行之后会出现段错误,而 -f 会立即出现段错误。

#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);
}
4

3 回答 3

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)or printf("%s", line)(一旦你修复了 line 的声明)。

int main

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

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

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

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

此测试不足以满足您的 -f 案例。

于 2012-09-25T02:15:05.017 回答
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);
}
于 2012-09-25T02:29:18.240 回答
0

你不需要

char* line[MAX_CHARACTERS_PER_LINE]; 

这是一个指向数组的指针(如果您想逐行存储文件或输入,这可能很有用)并且您没有先分配它。所以段错误非常明显。

将您的 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来解析您的参数。

于 2012-09-25T02:29:22.663 回答