c中的strstr函数和多维数组

strstr function and multi dimensional arrays in c

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

void find_track(char *search_for);
char tracks[][80] = {
    "I left my heart in Harvard Med School",
    "Newark, Newark - a wonderful town",
    "Dancing with a Dork",
    "From here to maternity",
    "The girl from Iwo Jima"
};

int main() {
    char *to_search_str;
    printf("Search for: ");
    fgets(to_search_str, 80, stdin);
    find_track(to_search_str);
    return 0;
}

void find_track(char *search_for) {
    int i;
    for (i=0; i<5; i++) {
        if (strstr(tracks[i], search_for)) {
            printf("Track %d: '%s'\n", i, tracks[i]);
        }
    }
}

该程序应该在 tracks 多维数组中的每个字符串中搜索一个字符串,但是 find_track 中的 strstr() 函数总是返回 null,无论输入如何(即使我们从 tracks 多维数组中输入字符串的子字符串)。我不知道为什么会这样?

编辑: 更正后

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

void find_track(char *search_for);
char tracks[][80] = {
    "I left my heart in Harvard Med School",
    "Newark, Newark - a wonderful town",
    "Dancing with a Dork",
    "From here to maternity",
    "The girl from Iwo Jima"
};

int main() {
    char to_search_str[80];
    printf("Search for: ");
    fgets(to_search_str, 80, stdin);
    to_search_str[strlen(to_search_str)-1] = '[=11=]';
    find_track(to_search_str);
    return 0;
}

void find_track(char *search_for) {
    int i;
    for (i=0; i<5; i++) {
        if (strstr(tracks[i], search_for)) {
            printf("Track %d: '%s'\n", i, tracks[i]);
        }
    }
}

输出

很可能是通过 fgets() 输入的问题。

  • 您正在读入一个未初始化的指针 to_search_str,它没有指向有效的内存位置。在这种情况下,您可以简单地将其更改为一个数组,例如 char to_search_str[80] = {0}; 并完成它。

  • 您需要 trim 存储在输入缓冲区中的尾随换行符。

    来自man page,(强调我的

fgets() reads in at most one less than size characters from stream and stores them into the buffer pointed to by s. Reading stops after an EOF or a newline. If a newline is read, it is stored into the buffer. A terminating null byte ('[=15=]') is stored after the last character in the buffer.

完成此操作的快速方法是 to_search_str[strcspn(to_search_str, "\n")] = 0;,但 this other answer

中提到了更强大的方法

char *to_search_str; 是一个未初始化的指针,写入它会导致未定义的行为。例如,您必须分配内存或使用数组 char to_search_str[100];

另外不要忘记 fgets 也会将换行符读入缓冲区,您必须将其删除。

您没有分配 to_search_str 指针,您传递给 fgetschar * 指针作为目标缓冲区。由于它实际上未初始化,这会导致通常以程序崩溃结束的未定义行为。

您只需要静态或动态地分配它。

最简单的解决方案是在堆栈中定义一个静态数组:

#include <string.h>

#define LEN 80

int main() {
    char to_search_str[LEN];

    printf("Search for: ");
    fgets(to_search_str, LEN, stdin);

    /* Remove trailing newline from the string to search */
    to_search_str[strcspn(to_search_str, "\n")] = 0;

    find_track(to_search_str);
    return 0;
}

数组的大小为 80,因为您将此数字用作 fgets 中的 size 参数。请注意使用 #define 作为常量 80,这样可以更轻松地更改它。

堆中的动态分配涉及使用 malloc() 函数(以及 free() 一旦不再需要数组):

#include <string.h>

#define LEN 80

int main() {
    char * to_search_str = malloc(LEN);

    printf("Search for: ");
    fgets(to_search_str, LEN, stdin);

    /* Remove trailing newline from the string to search */
    to_search_str[strcspn(to_search_str, "\n")] = 0;

    find_track(to_search_str);

    free(to_search_str);
    return 0;
}

注意: 因为 fgets 在输出缓冲区中保留尾随换行符 ``\n'`,我们必须将其删除。我使用 oneliner 描述的巧妙解决方案 here.

主要代码片段

char *to_search_str;
printf("Search for: ");
fgets(to_search_str, 80, stdin);

调用未定义的行为,因为指针 to_search_str 未初始化且具有不确定的值。

看来你的意思至少是

char to_search_str[80];
printf("Search for: ");
fgets(to_search_str, 80, stdin);

函数fgets可以在输入的字符串后附加换行符'\n'

您需要将其删除,例如通过以下方式

to_search_str[ strcspn( to_search_str, "\n" ) ] = '[=12=]';

函数 find_track 至少应该声明为

void find_track( const char *search_for);

虽然函数定义依赖于全局变量是个坏主意。

而且查找相关字符串的方法也不好。例如,用户可以输入一个仅包含一个字符 'a' 的字符串。在这种情况下,所有记录都将满足条件。您应该检查搜索到的字符串是否在数组中的字符串中形成一个单词(由空格分隔的字符序列)。