简体   繁体   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]);
        }
    }
}

The program is supposed to search for a string in every string in the tracks multi dimensional array but the strstr() function in the find_track is always returning null no matter the input (even if we input the a sub string of a string from tracks multi dimensional array).该程序应该在tracks多维数组中的每个字符串中搜索一个字符串,但是无论输入如何, find_trackstrstr()函数总是返回null(即使我们从tracks multi中输入一个字符串的子字符串)维数组)。 I don't know why this is happening?我不知道为什么会这样?

EDIT : After correction编辑:更正后

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

Output输出在此处输入图片说明

Most likely the issue with input via fgets() .很可能是通过fgets()输入的问题。

  • You are reading into an uninitialized pointer to_search_str , which does not point to a valid memory location.您正在读入未初始化的指针to_search_str ,该指针未指向有效的内存位置。 In this case, you can simply change this to an array, like char to_search_str[80] = {0};在这种情况下,您可以简单地将其更改为数组,例如char to_search_str[80] = {0}; and get done with it.并完成它。

  • You need to trim the trailing newline that's stored in the input buffer.您需要修剪存储在输入缓冲区中的尾随换行符。

    From the man page , ( emphasis mine )手册页,(强调我的

fgets() reads in at most one less than size characters from stream and stores them into the buffer pointed to by s. fgets()从流中读取至多小于 size 的字符,并将它们存储到 s 指向的缓冲区中。 Reading stops after an EOF or a newline.阅读在EOF或换行符后停止。 If a newline is read, it is stored into the buffer.如果读取换行符,则将其存储到缓冲区中。 A terminating null byte ( '\\0' ) is stored after the last character in the buffer.终止空字节 ( '\\0' ) 存储在缓冲区中的最后一个字符之后。

A quick way of getting that done is to_search_str[strcspn(to_search_str, "\\n")] = 0;一个快速完成的方法是to_search_str[strcspn(to_search_str, "\\n")] = 0; , but there are more robust ways mentioned in this other answer ,但是在另一个答案中提到了更强大的方法

You aren't allocating to_search_str pointer, the char * pointer you pass to fgets as the destination buffer.您没有分配to_search_str指针,即您传递给fgets作为目标缓冲区的char *指针。 Being it actually uninitialized, this causes undefined behavior that normally ends with a program crash.由于它实际上未初始化,这会导致未定义的行为,通常以程序崩溃结束。

You just need to allocate it, statically or dynamically.您只需要静态或动态地分配它。

The simplest solution consists in just defining a static array in the stack:最简单的解决方案是在堆栈中定义一个静态数组:

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

The size of the array is 80 because you use this number as the size parameter in fgets .数组的大小是 80,因为您使用这个数字作为fgets大小参数。 Please note the use of a #define for the constant 80, making possible to change it in a easier way.请注意对常量 80 使用#define ,可以更轻松地更改它。

The dynamic allocation in the heap involves the use of malloc() function (and free() as soon as the array is not needed anymore):堆中的动态分配涉及使用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;
}

Note: since fgets retains trailing newline ``\\n'` in the output buffer, we have to remove it.注意:由于fgets在输出缓冲区中保留了尾随换行符“\\n”,我们必须将其删除。 I used the clever oneliner solution described here .我使用了此处描述的巧妙的oneliner解决方案。

char *to_search_str; is an uninitialized pointer, writing to it will result in undefined behavior.是一个未初始化的指针,写入它会导致未定义的行为。 You have to allocate memory or use an array instead char to_search_str[100];您必须分配内存或使用数组代替char to_search_str[100]; for example.例如。

Also don't forget that fgets will also read the newline into the buffer, which you have to remove.另外不要忘记fgets还会将换行符读入缓冲区,您必须将其删除。

This code snippet in main这个代码片段在主

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

invokes undefined behavior because the pointer to_search_str is not initialized and has indeterminate value.调用未定义的行为,因为指向to_search_str的指针未初始化并且具有不确定的值。

It seems you at least mean看来你至少是个意思

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

The function fgets can append the new line character '\\n' to the entered string.函数fgets可以将换行符'\\n'附加到输入的字符串。

You need to remove it for example the following way您需要通过以下方式将其删除

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

The function find_track should be declared at least like函数find_track至少应该声明为

void find_track( const char *search_for);

Though it is a bad idea when a function definition relies on global variables.尽管当函数定义依赖于全局变量时这是一个坏主意。

Also the approach of finding relevant strings is not good.查找相关字符串的方法也不好。 For example the user can enter a string that contains only one character 'a' .例如,用户可以输入一个仅包含一个字符'a'的字符串。 In this case all records will satisfy the condition.在这种情况下,所有记录都将满足条件。 You should check that the searched string forms a word (a sequence of characters separated by spaces) in a string in the array.您应该检查搜索的字符串是否在数组中的字符串中形成了一个单词(由空格分隔的字符序列)。

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

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