繁体   English   中英

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_trackstrstr()函数总是返回null(即使我们从tracks multi中输入一个字符串的子字符串)维数组)。 我不知道为什么会这样?

编辑:更正后

#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] = '\0';
    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}; 并完成它。

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

    手册页,(强调我的

fgets()从流中读取至多小于 size 的字符,并将它们存储到 s 指向的缓冲区中。 阅读在EOF或换行符后停止。 如果读取换行符,则将其存储到缓冲区中。 终止空字节 ( '\\0' ) 存储在缓冲区中的最后一个字符之后。

一个快速完成的方法是to_search_str[strcspn(to_search_str, "\\n")] = 0; ,但是在另一个答案中提到了更强大的方法

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

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

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

#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大小参数。 请注意对常量 80 使用#define ,可以更轻松地更改它。

堆中的动态分配涉及使用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解决方案。

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

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

这个代码片段在主

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" ) ] = '\0';

函数find_track至少应该声明为

void find_track( const char *search_for);

尽管当函数定义依赖于全局变量时这是一个坏主意。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM