[英]Print out the third word in a string. C
因此,我试图编写一个包含句子并从第三个单词中打印出来的程序。 例如: one two three four
应打印出three four
。
现在,这段代码可以工作了,但是我不知道为什么,因为else
语句下的逻辑使它看起来似乎不应该这样做。
如果有人可以解释为什么会这样,将不胜感激。
这是代码:
#include <stdio.h>
#include <string.h>
#define SIZE 100
int main(void) {
char arr[SIZE];
char *point;
char again = 'n';
do {
int count = 0;
for (int i = 0; i < SIZE; i++) {
arr[i] = '\0';
}
printf("Enter a sentence:");
gets(arr);
for (int i = 0; i < SIZE; i++) {
if (arr[i] == ' ') {
count++;
}
}
if (count < 2) {
printf("The sentence is to short!\n");
} else {
count = 1; //shouldn't this be count = 0?
for (int i = 0; i < SIZE; i++) {
if (arr[i] == ' ') {
count++;
}
if (count == 2) {
point = &arr[i + 2]; //shouldn't this be [i+1]?
}
}
printf("%s\n", point);
}
printf("Do you want to try again? (y/n)");
scanf("%c", &again);
while (getchar() != '\n');
} while (again == 'y' || again == 'Y');
return 0;
}
您的代码有多个问题:
gets()
。 此功能已从C标准中删除,因为无法给它提供最大数量的字符以写入目标缓冲区,因此输入流中足够长的行将导致未定义的行为。 这是一个经典的安全漏洞。 使用fgets()
代替。 while循环while (getchar() != '\\n');
如果文件末尾没有换行符,将导致无限循环,如果您重定向输入一个空文件,则会发生无限循环。 您还应该检查EOF
:
while ((c = getchar()) != EOF && c != '\\n') continue;
fgets()
的返回值与NULL
比较来检查输入操作是否成功。 point = &arr[i+2];
应该是point = &arr[i+1]
。 这是使用字符串函数strspn
和strcspn
跳过空格和非空格的更正版本:
#include <stdio.h>
#include <string.h>
#define SIZE 100
#define WS " \t\n\r\v\f" /* white space characters */
int main(void) {
char arr[SIZE];
char *p;
for (;;) {
printf("Enter a sentence:");
if (fgets(arr, sizeof arr, stdin) == NULL)
break;
p = arr;
p += strspn(p, WS); /* skip initial spaces */
p += strcspn(p, WS); /* skip first word */
p += strspn(p, WS); /* skip spaces */
p += strcspn(p, WS); /* skip second word */
p += strspn(p, WS); /* skip spaces */
if (*p == '\0') {
printf("The sentence is too short!\n");
} else {
printf("%s", p);
}
printf("Do you want to try again? (y/n)");
if (fgets(arr, sizeof arr, stdin) == NULL)
break;
if (*arr != 'y' && *arr != 'Y')
break;
}
return 0;
}
另一种简单的方法来处理字计数走路,一个指针下你在你是否是一个国家循环保持跟踪串in
一个字(如果是增加字数),否则你是不是in
一个字,只是继续走向下缓冲(即遍历每个字符),直到找到下一个单词(或字符串结尾)为止。
在填充缓冲区并设置指向其的指针之后,逻辑很简单
#define MAXC 1024 /* buffer size (don't skimp) */
#define NWORD 3 /* output beginning with NWORD word */
...
char buf[MAXC] = "", /* buffer to hold line */
*p = buf; /* pointer to walk down buffer */
int n = 0, /* word counter */
in = 0; /* flag - in a word */
只是循环检查每个字符isspace()
和手柄设置你in
标志设置为1
(字)或0
(在之前或单词之间的空格),每次去时递增的计数器in
一个新词,并退出循环,当你计数达到3
,例如
for (; *p; p++) { /* loop over each char */
if (!in && !isspace(*p)) { /* if not in word and not space */
in = 1, n++; /* set in flag, increment words */
if (n == NWORD) /* if 3rd word, break */
break;
}
else if (isspace(*p)) /* if space */
in = 0; /* unset in flag */
}
将其全部放在一个简短的示例中,您可以执行与以下操作类似的操作:输入内容,直到在空行上单独按下Enter键,然后输出从第三个单词开始输入的每个句子,或者显示错误"too few words."
如果输入少于三个单词的句子,例如
#include <stdio.h>
#include <ctype.h>
#define MAXC 1024 /* buffer size (don't skimp) */
#define NWORD 3 /* output beginning with NWORD word */
int main (void) {
for (;;) { /* loop continually until empy-line */
char buf[MAXC] = "", /* buffer to hold line */
*p = buf; /* pointer to walk down buffer */
int n = 0, /* word counter */
in = 0; /* flag - in a word */
fputs ("\nenter sentence: ", stdout); /* prompt */
if (!fgets (buf, MAXC, stdin) || *buf == '\n') { /* read line */
puts ("all done!");
break;
}
for (; *p; p++) { /* loop over each char */
if (!in && !isspace(*p)) { /* if not in word and not space */
in = 1, n++; /* set in flag, increment words */
if (n == NWORD) /* if 3rd word, break */
break;
}
else if (isspace(*p)) /* if space */
in = 0; /* unset in flag */
}
if (n == NWORD) /* if 3 or more words */
fputs (p, stdout);
else /* other wise handle error */
fputs ("too few words.\n", stderr);
}
return 0;
}
使用/输出示例
$ ./bin/thirdword
enter sentence: one two three four five
three four five
enter sentence: one two
too few words.
enter sentence: one two three
three
enter sentence:
all done!
仔细检查一下,如果您还有其他问题,请告诉我。
count = 1;
//这不应该是计数= 0吗? 并point = &arr[i + 2];
//这不是[i + 1]吗?
以下回答两个问题。
count count count count
0 1 2 3
one two three four
i+0 i+1 i+2 i+3
point = &arr[i + 2];
连同printf("%s\\n", point);
表示从arr[i + 2]
地址打印所有字符,直到看到\\0
字符
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.