首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >返回空的Strstr

返回空的Strstr
EN

Stack Overflow用户
提问于 2016-05-26 01:49:25
回答 1查看 1.4K关注 0票数 0

我在下面的代码中使用strstr时遇到了问题。有人能告诉我为什么第108行的strstr ( printf()语句中记录的)返回NULL吗?我使用一个文件作为命令行参数(包含由\n和null结尾的三个单词),然后使用另一个文件作为stdin

例如:

代码语言:javascript
复制
./stream_search word_list.txt < paragraph.txt

目标:在paragraph.txt中打印出包含word_list.txt中单词的所有行

代码语言:javascript
复制
#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;
}
EN

回答 1

Stack Overflow用户

发布于 2016-05-26 02:26:27

您的代码中有两个问题,任何一个问题都会阻止它按预期工作。

  1. 您不会从要搜索的单词(或“用户输入”)的末尾移除换行符,因此只有在输入的末尾出现时,才能找到该单词。
  2. 使用错误的顺序调用带有参数的函数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)),指定数组的完整大小是非常安全和明智的。

将这些变化加在一起会产生以下结果:

代码语言:javascript
复制
#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和包含hello world的文件data并调用程序wm13的文件,我得到了示例输出:

代码语言:javascript
复制
$ 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
$
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37450275

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档