在字符数组中,我试图挑选出以字符开头或单词中包含该字符的单词。我可以用什么来实现这个目标?谢谢你!
如果我有一个数组,上面写着“农耕乐趣很好”。 我的输出应该是: 农业 乐趣 阿尔夫
#include <stdio.h>
#include <string.h>
int main(void) {
char list[50];
int i;
fgets(list, 50, stdin); //retrieve the string from the user
for(i = 0; i < 50; i++){
if(list[i] == 'z'){
printf("%c", list[i]);
}
}
最佳答案
虽然它仍然出现,但您希望根据您的输入和输出查找包含 'F'
或 'f'
的单词 - 您发布的代码正在寻找 if (list[i] == 'z')
相当令人困惑......无论你想完成什么,你永远不会解析包含 'F'
或 ' 的单词f'
来自输入行检查 'z'
。
每个人都需要一点帮助,所以让我们从您需要完成的任务开始,假设“农业乐趣 alf 很好。”
并且您想要“农业乐趣 alf”
出来。您需要完成的基本步骤是:
- 将用户输入读取到有效存储中;
- 将输入拆分为单个单词(称为字符串标记化);和
- 检查每个单词中是否有字符为
'F'
或'f'
,如果找到则输出该单词。
读取用户的输入
您应该因为选择 fgets
来获取用户的输入而受到赞扬。这(与 POSIX getline
一起)将是一个不错的选择。无论您选择哪种输入函数,您都需要通过检查返回(至少)来验证输入通过生成手动 EOF
(Linux 上的 Ctrl+d 或 Windows 上的 Ctrl+z)来确保用户提供了有效的输入并且没有取消),在您的情况下,您还应该验证用户输入的字符而不是简单地按 Enter。您可以执行类似于以下操作:
#include <stdio.h>
#include <string.h>
#define MAXC 1024 /* if you need a constanst, #define one (or more) */
int main (void) {
char str[MAXC]; /* storage for string */
...
fputs ("enter string: ", stdout); /* prompt */
/* validate user provided input, not ctrl+d(z) or just [Enter] */
if (!fgets (str, MAXC, stdin) || *str == '\n') {
fputs ("(user canceled or empty input)\n", stderr);
return 1;
}
现在,您已将用户输入(最多 1023
个字符)存储在 str
中,并在末尾附加了 '\n'
字符.
将 str
标记为单词
虽然有很多方法可以将字符串标记为单词,但一种简单的方法是使用恰当命名的 strtok
函数。请参阅strtok(3) - Linux manual page了解其使用详情。总之,它在第一次调用时将要标记化的字符串作为其输入,并使用一串分隔符将字符串拆分为单词。 (在所有后续调用中,将传递 NULL
来代替原始 str
)。
注意: strtok
修改原始 str
,因此您无法传递 string-literal 或其他不可变字符串。 (如果需要保留原始文件,请复制 str
)
要使用 strtok
进行标记化,您可以这样做:
const char *delim = " \t\n.?!", /* delimiters to split str */
*find = "fF"; /* chars to test for */
...
/* tokenize str into words */
for (char *p = strtok(str, delim); p; p = strtok (NULL, delim)) {
/* test for characters here */
}
上面的 for
循环声明一个字符指针 p
作为循环变量(初始化为 strtok(str, delim)
的返回值,其中将是指向第一个单词的指针。然后循环检查 p
(例如 p != NULL
)作为循环条件,并使用 p = strtok ( NULL, delim)
在每次迭代中确保 p
指向下一个单词。您可能会认为逻辑更简单一些:
char *p = strtok(str, delim);
while (p != NULL) {
/* test for characters here */
p = strtok (NULL, delim);
}
(两者是等效的)
检查单词是否包含要查找的字符
为了检查一个单词是否包含任意数量的字符之一,strpbrk
函数是量身定制的。请参阅strtok(3) - Linux manual page 。 strtok
将定位您在分隔符字符串(名为上面声明的 find
)中提供的任何一个字符的第一次出现,例如
if (strpbrk (p, find)) { /* does word contain fF? */
...
就是这样。现在您只需填写逻辑即可输出上面找到的单词。您可以简单地printf("%s", p);
。总而言之,你可以这样做:
#include <stdio.h>
#include <string.h>
#define MAXC 1024 /* if you need a constanst, #define one (or more) */
int main (void) {
char str[MAXC]; /* storage for string */
const char *delim = " \t\n.?!", /* delimiters to split str */
*find = "fF"; /* chars to test for */
fputs ("enter string: ", stdout); /* prompt */
/* validate user provided input, not ctrl+d(z) or just [Enter] */
if (!fgets (str, MAXC, stdin) || *str == '\n') {
fputs ("(user canceled or empty input)\n", stderr);
return 1;
}
/* tokenize str into words */
for (char *p = strtok(str, delim); p; p = strtok (NULL, delim)) {
if (strpbrk (p, find)) { /* does word contain fF? */
printf (" %s", p); /* output with space */
}
}
putchar ('\n'); /* tidy up with newline */
return 0;
}
示例使用/输出
$ ./bin/strtokspn
enter string: Farming fun alf is good.
Farming fun alf
这不是唯一的方法,但可能是解决该问题的更简洁的方法之一。仔细检查一下,如果有疑问请告诉我。
关于c - 查找以数组中的字符开头的单词,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57228404/