Aside from invoking Undefined Behavior by returning a pointer to a locally declared array in LongestWord
, using gets
despite gets() is so dangerous it should never be used! and writing beyond the end of the Solution
array -- you are missing the logic of identifying the longest word.
To identify the longest word, you must obtain the length of each word as you work you way down the string. You must keep track of what the longest string seen, and only if the current string is longer than the longest seen so far do you copy to valid memory that will survive the function return (and nul-terminate).
There are a number of ways to do this. You can use strtok
to tokenize all words in the string, you can use a combination of strcspn
and strspn
to bracket the words, you can use sscanf
and an offset to the beginning of each word, or what I find easiest is just to use a pair of pointers sp
(start-pointer) and ep
(end-pointer) to work down the string.
There you just move sp
to the first character in each word and keep moving ep
until you find a space (or end of string). The word length is ep - sp
and then if it is the longest, you can simply use memcpy
to copy length
characters to your longest word buffer and nul-terminate, (repeat until you run out of characters)
To create valid storage, you have two-choices, either pass an array of sufficient size (see comment), or declare a valid block of memory within your function using malloc
(or calloc
or realloc
) and return a pointer to that block of memory.
An example passing an array of sufficient size to hold the longest word could be:
#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);
}
(note: by using this method you ignore all leading, trailing and intervening whitespace, so strings like " my little dog has 1 flea . "
do not present problems.)
Example Use/Output
$ ./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)
There are many, many ways to do this. This is one of the most basic, using pointers. You could do the same thing using indexes, e.g. string[i]
, etc.. That just requires you maintain an offset to the start of each word and then do the subtraction to get the length. strtok
is convenient, but modifies the string being tokenized so it cannot be used with string literals or other constant strings.
Best way to learn is work the problem 3-different ways, and pick the one that you find the most intuitive. Let me know if you have further questions.