C语言strstr分段错误

时间:2013-01-27 01:36:01

标签: c pointers segmentation-fault strstr

我是初学者,tracks.c:

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

char tracks[][5] = {
    "one",
    "two",
    "three",
    "four",
    "five",
    "six",
};

void track_search(char search_for[]) {

    int i;
    puts(search_for);
    puts(strstr(tracks[0], search_for));

    /*
    for (i = 0; i < 6; i++) {
        if (strstr(tracks[i], search_for)) {
            printf("tracks %i: %s\n", i,tracks[i]);
        } else {
            puts("Nothing found");
        }
    }
    */
}

int main() {

    char search_for[5];

    printf("enter your word: ");
    fgets(search_for, 5, stdin);
    track_search(search_for);

    return 0;
}

$ gcc tracks.c&amp;&amp; ./a.out

输入您的字词:on

分段错误

但如果我使用puts(strstr(tracks [0],“on”));而不是puts(strstr(tracks [0],search_for)); 它会起作用酒,谁知道哪里出错了?

3 个答案:

答案 0 :(得分:2)

这有几个问题。

首先,未正确声明常量数组。

char tracks[][5] = {
    "one",
    "two",
    "three",
    "four",
    "five",
    "six",
};

这表示“声明一个任意长度char[5]的数组。紧紧盯着那个数组内容非常,并认为这些字符串的长度实际上是它的字符数加一个零终结者。有什么东西突然出现在你身上吗?也许是"three"这个词?那就是5 + 1,或者六个字符宽,而不是五个。 / p>

试试这个:

const char *tracks[] = 
{
    "one",
    "two",
    "three",
    "four",
    "five",
    "six"
};

还可以修改你的for循环:

for (i = 0; i < sizeof(tracks)/sizeof(tracks[0]); ++i) 
{
    if (strstr(tracks[i], search_for))
        printf("track[%d]: %s\n", i, tracks[i]);
}

注意:为了我自己的理智,我从循环中删除了多余的“Nothing found”。

最后,获取的字符串可能会在结尾处添加行尾('\n'),如果是这样,您应该检查并将其置空。我会显着延长输入缓冲区的大小,然后在它出现时修剪endl:

int main()
{
    char search_for[64] = {0};

    printf("enter your word: ");
    if (fgets(search_for, sizeof(search_for), stdin))
    {
        size_t len = strlen(search_for);
        if (len && search_for[len-1] == '\n')
            search_for[len-1] = 0;
        track_search(search_for);
    }
    else
    {
        perror("fgets failed.");
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}

答案 1 :(得分:1)

这是因为fgets读取换行符,因此"on\n"中找不到"one",因此strstr会返回NULL,如果传递给puts会导致分段错误}。

您可能希望在读取输入后首先删除换行符和其他空格,例如将新行/空格的第一次出现设置为0,如

char *p;
if(p = strchr(search_for, '\n')) *p = 0;
if(p = strchr(search_for, ' ')) *p = 0;

(同样char[5]"three"来说还不够,因为你需要额外的空终结符位置。)

答案 2 :(得分:1)

你必须考虑两件事:

如果单词不在列表中,strstr()返回一个NULL指针,你不能将它传递给puts(),所以这样做。

 char *found = strstr(tracks[0], search_for);
if (found)
    puts(found);
else
    puts("The word '%s' was not found\n",search_for);

一旦你这样做,你会发现fgets也会读取你输入的换行符。因此,如果您输入四个并按Enter键,您将搜索“四个\ n”因此您应该删除该\ n字符,例如做

char *p;
if ((p = strrchr(search_for, '\n')) != NULL) {
   *p = 0;
}

用fgets读取输入后。