[英]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
標記字符串中的所有單詞,可以使用strcspn
和strspn
的組合將strcspn
起來,可以使用sscanf
和每個單詞開頭的偏移量,或者我發現最簡單的方法是使用一對指針sp
(開始指針)和ep
(結束指針)對字符串進行處理。
在那里,您只需將sp
移到每個單詞的第一個字符,然后繼續移動ep
直到找到空格(或字符串的結尾)。 單詞長度是ep - sp
,然后如果它是最長的,則可以簡單地使用memcpy
將length
字符復制到最長的單詞緩沖區中,然后使用nul-terminate ,(重復操作直到字符用完)
要創建有效的存儲,您有兩種選擇,要么傳遞足夠大小的數組(請參見注釋),要么使用malloc
(或calloc
或realloc
)在函數中聲明一個有效的內存塊,然后返回指向該內存塊的指針。
傳遞足夠大以容納最長單詞的數組的示例可能是:
#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
很方便,但是會修改要標記化的字符串,因此不能與字符串文字或其他常量字符串一起使用。
最好的學習方法是將問題分為三種方法,然后選擇最直觀的方法。 如果您還有其他問題,請告訴我。
main
入口點: int main( int argc, const char* argv[] )
fgets
而不是gets
,因為gets不會檢查字符串的邊界(輸入120個字符的行時發生了什么) length
傳遞給LongestWord
strnlen
plain strlen
,在strnlen
情況下,可能無法正確終止字符串。 length
參數來限制循環並在遇到終止字符時中斷。 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.