[英]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
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.