簡體   English   中英

查找字符串中最長的單詞

[英]Finding Longest Word in a String

我是C編程的新手。 我已經編寫了代碼以查找字符串中最長的單詞。 我的代碼沒有顯示任何錯誤,但是它會打印出一個字符串中沒有奇怪字符的單詞。 您能告訴我代碼有什么問題嗎? 謝謝

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

char LongestWord (char GivenString[100]);

int main()
{
    char input[100];
    char DesiredWord[20];

    printf("please give a string:\n");
    gets(input);
       DesiredWord[20]=LongestWord(input);

    printf("longest Word is:%s\n",DesiredWord);

    return 0;
}

char LongestWord (char GivenString[100]){
    //It is a predefined function, by using this function we can clear the data from console (Monitor).
    //clrscr()
    int position1=0;
    int position2=0;
    int longest=0;
    int word=0;
    int Lenght=strlen(GivenString);
    char Solution[20];
    int p=0;

    for (int i=1; i<=Lenght; i++){
        if (GivenString[i-1]!=' '){
            word=word++;
    }
        if(GivenString[i-1]=' '){
            if (word>longest){
                //longest stores the length of longer word
                longest=word;
                position2=i-1;
                position1=i-longest;
                word=0;
                }
            }
        }
        for (int j=position1; j<=position2; j++){
                Solution[p]=GivenString[j];
                p=p++;
        }
return (Solution[20]);
}

這應該工作:

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

void LongestWord(char string[100])
{
    char word[20],max[20],min[20],c;
    int i = 0, j = 0, flag = 0;
     for (i = 0; i < strlen(string); i++)
    {
        while (i < strlen(string) && string[i]!=32 && string[i]!=0)
        {
            word[j++] = string[i++];
        }
        if (j != 0)
        {
            word[j] = '\0';
            if (!flag)
            {
                flag = !flag;
                strcpy(max, word);
            }
            if (strlen(word) > strlen(max))
            {
                strcpy(max, word);
            }
            j = 0;
        }
    }
    printf("The largest word is '%s' .\n", max);

}


int main()
{
   char string[100];
    printf("Enter string: ");
    gets(string);
    LongestWord(string);
}

除了通過返回指向LongestWord本地聲明的數組的指針來調用Undefined Behavior之外,使用gets盡管gets()還是很危險的,永遠不要使用它! 並在Solution數組的末尾進行書寫-您缺少識別最長單詞的邏輯。

為了識別最長的單詞,您必須在沿字符串向下移動時獲得每個單詞的長度。 您必須跟蹤看到的最長的字符串,只有當當前字符串比迄今為止的最長的字符串長時,才可以復制到有效的內存中,該內存將在函數返回(和nul-terminate )之后繼續存在。

有很多方法可以做到這一點。 您可以使用strtok標記字符串中的所有單詞,可以使用strcspnstrspn的組合將strcspn起來,可以使用sscanf和每個單詞開頭的偏移量,或者我發現最簡單的方法是使用一對指針sp (開始指針)和ep (結束指針)對字符串進行處理。

在那里,您只需將sp移到每個單詞的第一個字符,然后繼續移動ep直到找到空格(或字符串的結尾)。 單詞長度是ep - sp ,然后如果它是最長的,則可以簡單地使用memcpylength字符復制到最長的單詞緩沖區中,然后使用nul-terminate ,(重復操作直到字符用完)

要創建有效的存儲,您有兩種選擇,要么傳遞足夠大小的數組(請參見注釋),要么使用malloc (或callocrealloc )在函數中聲明一個有效的內存塊,然后返回指向該內存塊的指針。

傳遞足夠大以容納最長單詞的數組的示例可能是:

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

#define MAXW  256    /* longest word buffer size */
#define MAXC 1024    /* input string buffer size */

size_t longestword (char *longest, const char *str)
{
    int in = 0;             /* flag reading (in/out) of word */ 
    size_t max = 0;         /* word max length */
    const char  *sp = str,  /* start-pointer for bracketing words */
                *ep = str;  /* end-pointer for bracketing words */

    *longest = 0;           /* initialize longest as empty-string */

    for (;;) {                          /* loop over each char in str */
        if (isspace (*ep) || !*ep) {    /* is it a space or end? */
            if (in) {                   /* are we in a word? */
                size_t len = ep - sp;   /* if so, get word length */
                if (len > max) {        /* is it longest? */
                    max = len;          /* if so, set max to len */
                    memcpy (longest, sp, len);  /* copy len chars to longest */
                    longest[len] = 0;   /* nul-terminate longest */
                }
                in = 0;     /* it's a space, no longer in word */
            }
            if (!*ep)       /* if end of string - done */
                break;
        }
        else {              /* not a space! */
            if (!in) {      /* if we are not in a word */
                sp = ep;    /* set start-pointer to current */
                in = 1;     /* set in flag */
            }
        }
        ep++;       /* increment end-pointer to next char */
    }

    return max;     /* return max length */
}

int main (void) {

    char str[MAXC] = "",    /* storage for input string */
        word[MAXW] = "";   /* storage for longest word */
    size_t max = 0;         /* longest word length */

    fputs ("enter string: ", stdout);   /* prompt */
    if (!fgets (str, MAXC, stdin)) {    /* validate input */
        fputs ("(user canceled input)\n", stderr);
        return 1;
    }

    if ((max = longestword (word, str)))    /* get length and longest word */
        printf ("longest word: %s  (%zu-chars)\n", word, max);
}

注意:通過使用此方法,您將忽略所有前導,尾隨和中間的空格,因此" my little dog has 1 flea . "類的字符串不會出現問題。)

使用/輸出示例

$ ./bin/longest_word
enter string: my dog has fleas
longest word: fleas  (5-chars)

$ ./bin/longest_word
enter string:   my   little dog   has 1 flea  .
longest word: little  (6-chars)

有很多很多方法可以做到這一點。 這是最基本的使用指針之一。 您可以使用索引來執行相同的操作,例如string[i]等。這只需要保持每個單詞開頭的偏移量,然后進行減法以獲得長度。 strtok很方便,但是會修改要標記化的字符串,因此不能與字符串文字或其他常量字符串一起使用。

最好的學習方法是將問題分為三種方法,然后選擇最直觀的方法。 如果您還有其他問題,請告訴我。

  1. 請聲明一個適當的main入口點: int main( int argc, const char* argv[] )
  2. 使用fgets而不是gets ,因為gets不會檢查字符串的邊界(輸入120個字符的行時發生了什么)
  3. 將期望字符串的length傳遞給LongestWord
  4. 如果可用,則首選使用strnlen plain strlen ,在strnlen情況下,可能無法正確終止字符串。
  5. 最好還是使用建議的length參數來限制循環並在遇到終止字符時中斷。
  6. 您的Solution是一個堆棧分配的數組,按原樣返回它可能取決於您的實現,您最好返回一個堆分配的數組(使用malloc)。

建議的變更

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

char* getLongestWord(char* input, size_t input_length, size_t *result_length);

int main( int argc, const char* argv[] ) 
{
    const size_t max_length = 100;
    char input[max_length]; // consider using LINE_MAX from limits.h
    printf("please give a string:\n");
    if ( fgets( input, max_length, stdin ) == NULL ) return EXIT_FAILURE; // some failure happened with fgets.
    size_t longestWord_length = 0;
    char* longestWord = getLongestWord(input, max_length , &longestWord_length);
    printf("longest Word is %.*s\n",longestWord_length, longestWord );
    return EXIT_SUCCESS;
}

char* getLongestWord(char* input, size_t input_length, size_t *result_length) {
    char* result = NULL;
    size_t length = 0;

    size_t word_start = 0, word_end = 0;

    for(int i = 0; i < input_length; ++i) {
        if( (input[i] == ' ') || (input[i] == 0) ) {
            if( i == 0 ) { // first space
                word_start = 1;
                continue;
            }
            word_end = i-1;
            size_t word_length = word_end - word_start+1;
            if( word_length <= length ) {
                word_start  = i + 1; // next word start
                continue;
            }
            // new max length
            length = word_length;
            result = &input[word_start];

            word_start  = i + 1; // next word start
        }
        if( input[i] == 0 ) break; // end of string
    }
    *result_length = length;
    return result;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM