打印出字符串中的第三个单词。C

打印出字符串中的第三个单词。C,c,C,所以我试着写一个程序,把一个句子从第三个单词中打印出来。Ex1234应打印出344 现在这个代码可以工作了,但我不知道为什么,else语句下的逻辑使它看起来不应该工作 如果有人能解释为什么它会这样工作,我会很感激的 代码如下: #include <stdio.h> #include <string.h> #define SIZE 100 int main(void) { char arr[SIZE]; char *point; char aga

所以我试着写一个程序,把一个句子从第三个单词中打印出来。Ex
1234
应打印出
344

现在这个代码可以工作了,但我不知道为什么,
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;
}
#包括
#包括
#定义大小100
内部主(空){
字符arr[大小];
字符*点;
char再次='n';
做{
整数计数=0;
对于(int i=0;i
count=1//这不应该是count=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”,点)
表示从地址
arr[i+2]
打印所有字符直到看到
\0
字符

您的代码有多个问题:

  • 永远不要使用
    get()
    。此函数已从C标准中删除,因为无法为其指定写入目标缓冲区的最大字符数,因此输入流中任何足够长的行都将导致未定义的行为。这是一个典型的安全缺陷。改用
    fgets()
  • 循环
    while(getchar()!='\n')将导致无限循环,如果重定向输入一个空文件,则会发生这种情况。您还应该检查
    EOF

    while ((c = getchar()) != EOF && c != '\n')
        continue;
    
  • 无需初始化目标数组,但应通过比较
    fgets()
    的返回值与
    NULL
    来检查输入操作是否成功
  • 在遍历数组以计数空格时,应在null终止符处停止。空终止符之外的数组的内容在输入操作之后是不确定的,如果您在调用之前初始化了它,则甚至是
  • 跳过单词的代码很麻烦,也不容易验证。实际上,
    point=&arr[i+2]应该是
    点=&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;
}
#包括
#包括
#定义大小100
#定义WS“\t\n\r\v\f”/*空格字符*/
内部主(空){
字符arr[大小];
char*p;
对于(;;){
printf(“输入一个句子:”);
如果(fgets(arr,sizeof arr,stdin)=NULL)
打破
p=arr;
p+=strspn(p,WS);/*跳过初始空格*/
p+=strcspn(p,WS);/*跳过第一个单词*/
p+=strspn(p,WS);/*跳过空格*/
p+=strcspn(p,WS);/*跳过第二个单词*/
p+=strspn(p,WS);/*跳过空格*/
如果(*p=='\0'){
printf(“句子太短!\n”);
}否则{
printf(“%s”,p);
}
printf(“您想再试一次吗?(是/否)”);
如果(fgets(arr,sizeof arr,stdin)=NULL)
打破
如果(*arr!=“y”&&&*arr!=“y”)
打破
}
返回0;
}

另一种处理字数的简单方法是在状态循环中沿字符串向下走一个指针,跟踪您是否在
一个字中(如果是这样,则增加字数),否则您不在
一个字中,只需沿着缓冲区走一走(即迭代每个字符),直到找到下一个字为止(或字符串的末尾)

在填充缓冲区并设置指向它的指针后,逻辑很简单,例如

#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
(在word中)或
0
(在单词之前或单词之间的空格中)每次进入
新词时递增计数器,并在计数达到
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键,然后输出从第三个单词开始输入的每个句子,或者显示错误
“单词太少”。
如果输入的句子少于三个单词,例如

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

仔细检查一下,如果您还有其他问题,请告诉我。

您尝试过strtok吗?那么问题是代码为什么工作?您编写了代码,问问自己它为什么工作。如果有疑问,请逐步使用调试器,观察所有变量,如果用户想多次重复循环,
scanf(%c),&再次)
应该是
scanf(“%c”,&再次);
注意添加的空格。奇怪的是,你认为使用
“\t”
然后使用
“\t\n”
“\t\n”
在整个过程中有什么价值?A
定义WS\t\n\r\v\f”和
str(c)spn(p,WS)
$ ./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!