【问题标题】:Program to find the longest word in a string查找字符串中最长单词的程序
【发布时间】:2018-11-25 02:30:15
【问题描述】:

我编写了一个程序来查找字符串中的最长单词并打印最长单词中的字母数。但是代码没有打印。我对程序分析了很多次,但找不到解决方案。

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

int main() {
    char string[100] = "Hello Kurnool";
    int i = 0, letters = 0, longest = 0;

start:

    for (; string[i] !=' '; i++) {
        letters++;  
    }

    if (letters >= longest)
        longest = letters;

    if (string[i] == ' ') {
        letters = 0;
        i++;
        goto start;
    }

    printf("%d", longest);

    return 0;
} 

【问题讨论】:

  • 阅读how to debug small programs。编译所有警告和调试信息:gcc -Wall -Wextra -gGCC。改进您的代码以获得没有警告。 use the gdb debugger。请注意 stdout 已缓冲(因此请使用 fflush 或以 \n 结束每个 printf 格式字符串...)
  • 不要使用 goto。
  • 你不检查字符串结尾更改测试for(;string[i]!=' ' &amp;&amp; string[i]!=0;i++)
  • 为什么要避免 goto:因为 Dijkstra told us 在 1968 年
  • 嘿伙计们,你们听说过 goto 被认为是有害的吗!?让我们辩论一下吧,肯定以前没有人这样做过。

标签: c string loops


【解决方案1】:

首先,请避免使用 Goto,这不是一个好习惯。

其次,您的循环在第二次迭代时将运行无限次,因为:

for(;string[i]!=' ';i++) // Here String[i] will never be equal to ' ' As there is no white space after your last word.

【讨论】:

    【解决方案2】:

    强烈建议不要使用goto。您应该将代码转换为使用循环。

    你的代码中的主要问题是当你到达字符串的末尾时你没有停止扫描。

    这是修改后的版本:

    #include <stdio.h>
    
    int main() {
        char string[100] = "Hello Kurnool";
        int i, letters, longest = 0, longest_pos = 0;
    
        for (i = 0; string[i] != '\0'; i++) {
            for (letters = 0; string[i] != '\0' && string[i] != ' '; i++) {
                letters++;  
            }
            if (letters > longest) {
                longest = letters;
                longest_pos = i - longest;
            }
        }    
        printf("longest word: %d letters, '%.*s'\n",
               longest, longest, string + longest_pos);
    
        return 0;
    }
    

    请注意,实现可以简化为单个循环:

    #include <stdio.h>
    
    int main() {
        char string[100] = "Hello Kurnool";
        int i, start = 0, longest = 0, longest_pos = 0;
    
        for (i = 0; string[i] != '\0'; i++) {
            if (string[i] == ' ') {
                start = i + 1;
            } else {
                if (i - start > longest) {
                    longest = i - start;
                    longest_pos = start;
                }
            }
        }    
        printf("longest word: %d letters, '%.*s'\n",
               longest, longest, string + longest_pos);
    
        return 0;
    }
    

    【讨论】:

    • 您错过了将大括号 {} 放在 if (letters &gt; longest) 块中,因此程序可能无法在其他情况下提供正确的输出。语句longest = letters;longest_pos = i - longest; 应该在if 块{} 内。
    • 不错的改进。
    【解决方案3】:

    以下是我的方法。您应该使用 C 的字符串操作函数。这是在 C 中处理字符串的正确方法。

    在下面的代码中,首先我获取了将输入字符串存储在堆中所需的字节。然后我使用strtok 将字符串拆分为基于 delemeter 的标记,并获取每个子字符串的长度。最后我释放了我用malloc分配的空间。

    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    
    #define phrase "Hello Kurnool"
    int main()
    {
        char* string = malloc(strlen(phrase)+1);
        strcpy(string,phrase);
        int longest=0;
        char *token;
        char delimeter[2] = " ";
    
       /* get the first token */
       token = strtok(string, delimeter);
    
       /* walk through other tokens */
        while( token != NULL ) {
            printf( " %s\n", token );
            if(longest < strlen(token)){
                longest = strlen(token);
            }
            token = strtok(NULL, delimeter);
       }
        printf("%d",longest);
        free(string);
        return 0;
    }
    

    【讨论】:

    • 可以使用strspn()strcpsn() 代替strtok(),因此不需要malloc()strlen()free()
    【解决方案4】:

    如果您正在使用,您永远无法预料到您的程序会出现什么问题

    goto 语句

    永远不建议使用它,如果你使用它,那就是糟糕的编程。其次,您似乎陷入了无限循环,因此她可以解决您的问题:

    #include<stdio.h>
    #include<string.h>
    void main()
    {
        char s[1000];
        scanf("%s",s);
        int i=0;
        int letters;
        int longest=0;
        while(s[i]!=NULL)
       {
          if(s[i]==' ')
          {
             if(longest>=letters)
                  {longest=letters;}
             letters=0;
           }
          else
             {letters++;}
        }
    printf("%d\n",longest);
    }
    

    所以,我所做的是假设一个字符串 s 是用户给出的输入。您遍历 s 直到用户给出的最后一个输入,之后它遇到一个 NULL 字符。现在您正在搜索最长单词的长度,因此您创建了一个变量 letters 来计算编号。字符串的每个单词中的字母。如果字符串 s 遇到表示单词结尾的空格,则检查变量 longest 是否大于或小于字数。再次将 letters 初始化为 0,以便它可以再次从 0 开始计算下一个单词。所以,通过这种方法在结束时,即在 while 循环终止之后,我们获取我们需要的输出,它存储在变量 longest 中。 所以,我想这会打印出号码。最长单词中的字母。

    【讨论】:

      【解决方案5】:

      人们说 - dont use gotogoto 本身并没有错。唯一的问题是,如果不明智地使用goto,它会使代码更难理解和维护。例如,您在程序中使用它的方式(而不是goto,循环非常适合这种情况)。检查这个:
      To use goto or not?
      What is wrong with using goto?

      在您的代码中,for 循环条件没有检查终止空字符

      for (; string[i] !=' '; i++) {
      

      因此它不会停在字符串的末尾。
      要查找字符串中最长单词中的字母数,您可以这样做:

      #include <stdio.h>
      #include <string.h>
      
      int main() {
          char string[100] = "Hello Kurnool";
          int i, letters = 0, longest = 0;
      
          for (i = 0; string[i] != '\0'; i++) {
              if (string[i] != ' ') {
                  letters++;
                  if (letters > longest) {
                      longest = letters;
                  }
              } else {
                  letters = 0;
              }
          }
      
          printf("longest : %d\n", longest);
      
          return 0;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-07-04
        • 2011-07-21
        • 2016-06-14
        • 2021-05-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多