如何查找字符串中每个单词的长度?

问题描述 投票:3回答:4

我编写了一个代码,该代码接受一个句子并输出一行中的每个单词。但我也想在每个单词旁边写上它的大小。

输入:

Hi my name is

当前输出:

Hi
my
name
is

所需的输出:

Hi(2)
my(2)
name(4)
is(2)

我当前的代码:

#include <stdio.h>

#define MAX 100

int main(void) {

    int c = 0;
    size_t n = 0;

    printf("\n Enter a sentence.\n\n input: ");

    /* read up to 100 characters from stdin, print each word on a line */
    while (n < MAX && (c = getchar()) != EOF && c != '\n')
    {
        if (c == ' ')
            printf("\n");
        else
            printf("%c", c);
        n++;
    }
    printf("\n");

    if (n == MAX) /* read and discard remaining chars in stdin */
        while ((c = getchar()) != '\n' && c != EOF);

    return 0;
}

我该怎么做?

c tokenize c-strings string-length
4个回答
1
投票

还有一个变量,当您按下空格时将打印出来。

size_t len = 0;

/* read up to 100 characters from stdin, print each word on a line */
while (n < MAX && (c = getchar()) != EOF && c != '\n')
{
    if (c == ' ') {
        printf("(%u)\n", len);
        len = 0;
    }
    else {
        len++;
        printf("%c", c);
    }
    n++;
}

1
投票

为了完整性,一种方法是在一个调用中读取整个输入,然后将其标记化:

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

#define MAX (100)

int main(void) 
{
  int result = EXIT_SUCCESS; /* Be optimistic. */ 
  char s[MAX +1];

  printf("\n Enter a sentence.\n\n input: ");

  /* read up to 100 characters from stdin, print each word on a line */

  if (NULL == fgets(s, sizeof s, stdin))
  {
    if (ferror(stdin))
    {
      perror("fgets() failed");
      result = EXIT_FAILURE;
    }
  }
  else
  {
    s[strcspn(s, "\r\n")] = '\0'; /* chop off carriage return, line feed, if any */

    for (char * pc = strtok(s, " "); NULL != pc; pc = strtok(NULL, " "))
    {
      printf("%s (%zu)\n", pc, strlen(pc));
    }
  }

  return result;
}

由于从未明确使用过读取缓冲区,因此以下变体也是可能的:

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

#define MAX (100)

int main(void) 
{
  int result = EXIT_SUCCESS; /* Be optimistic. */ 

  printf("\n Enter a sentence.\n\n input: ");

  {
  /* read up to 100 characters from stdin, print each word on a line */    
    char * pc = fgets((char[MAX+1]), MAX+1, stdin);
    if (NULL == pc)
    {
      if (ferror(stdin))
      {
        perror("fgets() failed");
        result = EXIT_FAILURE;
      }
    }
    else
    {
      pc[strcspn(pc, "\r\n")] = '\0'; /* chop off carriage return, line feed, if any */

      for (pc = strtok(pc, " "); NULL != pc; pc = strtok(NULL, " "))
      {
        printf("%s (%zu)\n", pc, strlen(pc));
      }
    }
  }

  return result;
}

0
投票

除了@kiranBiradar的好答案之外,您可能还想添加一个附加变量,该变量可用来跟踪您是in-a-word读取字符还是out-a-word阅读空白。 (只需要使用简单的int值作为flag设置为1(true)来表示单词内或0(false)非单词内就可以了)这将允许您忽略输入中的前导空格,多个包含的空格或结尾的空格,例如,如果您的输入类似于:

"   my       dog   has      fleas   and my   cat has   none  "

除非您一直跟踪读取状态,无论您是字内/非字内,每次读取空白字符都将输出多次出现的"(0)\n"。通过保留标志是否为in / not-in单词并将其在单词中读取非空格字符后遇到第一个空格时将其设置为零,可以使您仅在第一个空格上输出一次长度遇到空白。

此外,除非您退出读取循环后再输入其他代码,否则以c != '\n'为条件的读取将跳过输出最后一个字的长度。

还通过包含<ctype.h>,您还具有isspace()宏可用于检查all空格(例如space, tab, newline, backspace, vertical-tab等...),它大大简化了条件检查。

完全可以将其放入:

#include <stdio.h>
#include <ctype.h>      /* for isspace() */

int main (void) {

    int c = 0, in = 0, len = 0;             /* char, in/out flag, length */

    fputs ("enter text: ", stdout);         /* prompt for text */
    fflush (stdout);                        /* (optional), but recommended */

    while ((c = getchar()) != EOF) {        /* loop reading chars until EOF */
        if (isspace (c)) {                  /* if input is space */
            if (in) {                       /* check if in-word */
                printf ("(%d)\n", len);     /* output (len) */
                len = 0;                    /* reset len zero */
                in = 0;                     /* set in flag zero (false) */
            }
            if (c == '\n')                  /* if space is \n */
                break;                      /* break read loop */
        }
        else {  /* if not whitespace */
            putchar (c);                    /* output char */
            len++;                          /* increment length */
            in = 1;                         /* set in flag 1 (true) */
        }
    }
}

[note:没有理由将读取限制为n < MAX,除非您只是想任意将字符读取限制为前100个字符。没有填充数组或占用其他存储空间用字符c(除了一个字节)。如果输入包含十亿,则可以读取十亿。)

示例使用/输出

$ ./bin/getchar_word_len
enter text:      my       dog   has      fleas   and my   cat has   none
my(2)
dog(3)
has(3)
fleas(5)
and(3)
my(2)
cat(3)
has(3)
none(4)

查看两个答案,如果还有其他问题,请告诉我们中的一个。如果您对逻辑感到困惑,请取出一张8.5x11的纸,并从输入的开头开始对每个字符进行循环逻辑研究。当您处理第一个单词时,这将是有意义的。


-5
投票

前几天我实际上遇到了这个问题,我发现了此解决方案的问题

© www.soinside.com 2019 - 2024. All rights reserved.