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

时间:2019-11-19 04:03:05

标签: c tokenize c-strings string-length

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

输入:

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

我该怎么做?

3 个答案:

答案 0 :(得分:2)

出于完整性考虑,采用另一种方法在一次调用中读取整个输入,然后将其标记化:

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

答案 1 :(得分: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++;
}

答案 2 :(得分:0)

除了@kiranBiradar给出的好答案之外,您可能还想添加一个附加变量,该变量可用来跟踪您是字面上的 阅读字符还是外面的单词空白。 (使用简单的int值作为 flag 设置为1(真)以用于词内或0(假)非词以全部(如果需要),这将使您忽略输入中的前导空格,多个包含的空格或结尾的空格,例如,如果您输入的内容类似于:

"   my       dog   has      fleas   and my   cat has   none  "

除非您一直跟踪阅读状态,否则无论您是字词还是非字词,每次出现"(0)\n"时,您都会输出多次读取空白字符。通过保留一个标记来指示您是否在一个单词中,并在遇到单词后读取非空白字符后遇到第一个空白时将其设置为零,从而使您只能输出一次长度在遇到的第一个空白处。

另外,除非您退出读取循环后再添加其他代码,否则对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) */
        }
    }
}

注意:没有理由将读取限制为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的纸,并从输入开始就对每个字符进行循环逻辑研究。当您完成第一个单词时,这将是有意义的。