我在使用以下代码尝试使用strstr时遇到了问题。任何人都可以向我指出为什么第108行(strstr
语句中记录)的printf()
返回NULL?我使用一个文件作为我的命令行参数(包含由\ n分隔的三个单词并以null结尾),然后将另一个文件用作stdin
。
例如:
./stream_search word_list.txt < paragraph.txt
目标:打印出包含word_list.txt中单词的paragraph.txt中的所有行
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define INPUTSIZE 1000
#define LINESIZE 100
/*
Read one line of a given file f into the array buffer.
*/
char* read_line(FILE* f, char buffer[LINESIZE]) {
//reads line until n-1 char read, \n read, \o read, or EOF reached
fgets(buffer, LINESIZE-1, f);
printf("line 38: read line: %s\n", buffer);
return buffer;
}
/*
Prints the string in array buff.
*/
void print_buff(char buff[LINESIZE]) {
printf("print_buff: %s\n", buff);
}
/*
Read lines from standard input and store in array p.
*/
char* get_input(char p[INPUTSIZE]) {
fgets(p, INPUTSIZE-1, stdin);
printf("line 76: %s\n", p);
return p;
}
int main(int argc, char* argv[]) {
char words[LINESIZE];
char user_input[INPUTSIZE];
/*
* Prints error if program was called with
* no command line arguments,
* or with more than one argument.
*/
if(argc != 2) {
fprintf(stderr, "Usage: ./stream_search <word list file> \n");
return 0;
}
//assume argv[1] is a filename to open
FILE* file = fopen (argv[1], "r");
//Print error if file cannot be opened
if (file == NULL) {
fprintf(stderr, "Unable to open word list \n");
return 0;
}
read_line(file, words); //get input from file
get_input(user_input); //get input from stdin
printf("line 98: %s", words);
printf("line 101: %s", user_input);
char* a = "hello";
char* b = "hel";
printf("line 103: %s\n", strstr(a, b));
printf("line 108: %s\n", strstr(words, user_input));
fclose(file);
return 0;
}
答案 0 :(得分:1)
您在代码中遇到两个问题,其中任何一个都会阻止它按预期工作。
strstr()
。调用需要符合strstr(haystack, needle)
的顺序,而不是代码中使用的strstr(needle, haystack)
顺序。换句话说,通话需要strstr(user_input, words)
而不是strstr(words, user_input)
。您有一个未使用的功能print_buff()
。您有两个非常相似的函数,通过将文件流和缓冲区大小作为参数传递,可以很容易地组合成一个函数。这也可以让你有一个地方删除换行符。请注意,如果数组为char buffer[BUFLEN];
,则使用fgets(buffer, BUFLEN, fp)
(通常更好地使用fgets(buffer, sizeof(buffer), fp)
)非常安全且理智,指定数组的完整大小。
将这些变化放在一起产生:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define INPUTSIZE 1000
#define LINESIZE 100
static void read_line(FILE *f, size_t bufsiz, char buffer[])
{
fgets(buffer, bufsiz, f);
buffer[strcspn(buffer, "\n")] = '\0';
}
int main(int argc, char *argv[])
{
char words[LINESIZE];
char user_input[INPUTSIZE];
if (argc != 2)
{
fprintf(stderr, "Usage: ./stream_search <word list file> \n");
return 0;
}
FILE *file = fopen(argv[1], "r");
if (file == NULL)
{
fprintf(stderr, "Unable to open word list \n");
return 0;
}
read_line(file, sizeof(words), words);
read_line(stdin, sizeof(user_input), user_input);
printf("line 98: %s\n", words);
printf("line 101: %s\n", user_input);
printf("line 108: %s\n", strstr(words, user_input));
printf("line 109: %s\n", strstr(user_input, words));
fclose(file);
return 0;
}
请注意,printf()
的所有实现都不会优雅地处理空指针;他们有权发生崩溃,如果他们这样做,IMO会更好。但是,我没有修复这个代码 - (un)幸运的是,我正在使用的系统有printf()
打印(null)
而不是在给出空指针打印为字符串时崩溃
如果文件words
包含行hel
,文件data
包含hello world
,并调用程序wm13
,则会获得示例输出:
$ gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \
-Wold-style-definition -Werror wm13.c -o wm13
$ ./wm13 words < data
line 98: hel
line 101: hello world
line 108: (null)
line 109: hello world
$