0

I have a code, which prints the longest word in a string.

I need it to print this string without this particular word. Hope you can help me with it, example: Input: ''The longest word'' Output: ''The word''

#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);
}
coot
  • 7
  • 2
  • https://stackoverflow.com/questions/1694036/why-is-the-gets-function-so-dangerous-that-it-should-not-be-used – DarkAtom Dec 12 '22 at 20:04

2 Answers2

0

I took a crack at this, but I edited some of what you already had, so please pay attention to the comments:

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

void LongestWord(char string[100]) {
    char word[20], max[20];
    int  i = 0, j = 0;

    max[0] = '\0';  /* no more need for flag, strlen(max) == 0 */

    /* We want to store a pointer to the longest
     * word, within `string`.
     */
    const char* longest = string;

    /* we are going to put null terminators in here,
     * so let's just get this up front...
     */
    int string_length = strlen(string);

    for (i = 0; i < string_length; i++) {
        /* Save the beginning of the word. If it is
         * the longest, we will have a pointer to it.
         */
        const char* begin = &string[i];

        /* Let's use isspace so we can catch tabs
         * and line feeds as well.
         */
        while (i < string_length && !isspace(string[i]) && string[i] != 0) {
            word[j++] = string[i++];
        }
        if (i < string_length) {
            /* Put null terminators on spaces */
            string[i] = '\0';
        }
        if (j != 0) {
            word[j] = '\0';
            if (strlen(word) > strlen(max)) {
                longest = begin;
                strcpy(max, word);
            }
            j = 0;
        }
    }
    printf("The largest word is '%s' .\n", max);

    /* Loop through string and print all words,
     * unless we are on the longest word.
     */
    int len = 0;
    for (i = 0; i < 100; i += len + 1) {
        const char* it = &string[i];
        len = strlen(&string[i]);
        if (it == longest) {
            continue;
        }
        if (len == 0) {
            break;
        }
        printf("%s ", it);
    }
    puts("");
}


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

Don't use gets. Forget it even exists. I used fgets. fgets will copy the line terminator along with the string, so I switched to using isspace instead of looking for ' ' (32) specifically.

I got rid of the flag boolean. That appeared (guess since name is unhelpful) to be a hack to always accept the first word as the longest. Rather than have a hack in the middle of your logic, just make max a 0 length string. Then, it will always pass the "is this longer" test.

We have the original string and we can edit it. I'm overwriting your spaces for '\0'. Now you have an array with multiple embedded strings. Also, I save a pointer to the longest word as we go. When we print the string back to the user, we can just use the original string. It's been divided into individual strings that we can print 1 by 1. When we reach the longest word, longest will be pointing to the same place as &string[i]. All we need to do is skip that one...

Jason
  • 2,493
  • 2
  • 27
  • 27
0

Another version to consider. Trying to use fewer variables.

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

void func( char *phrase ) {
    // declare some variables and make a copy of the phrase for chopping-up
    char *cpy = strdup( phrase ), *plw = NULL, *cp;
    int len, max = 0;

    // use strtok() to isolate words in the copy, measure lengths, remember longest
    for( cp = cpy; (cp = strtok( cp, " \t\n" ) ) != NULL; cp = NULL )
        if( ( len = strlen( cp ) ) > max )
            plw = cp, max = len;

    // deal with string (original buffer) beyond the longest word
    char *rest = phrase + (plw - cpy) + max;
    if( *rest ) {
        while( isspace( *rest) ) rest++; // skip over spaces
        if( ( cp = strchr( rest, '\n' ) ) != NULL ) // clobber original LF
            *cp = '\0';
    }

    // print longest from copy, then pre-/post-amble from original
    printf( "Phrase: '%s'\n", phrase );
    printf( "Longest word: '%s'\n", plw );
    printf( "Phrase now: '%.*s%s'\n", plw - cpy, phrase, rest );

    free( cpy ); // tidy up
}

int main( void ) {
    char phrase[ 256 ] = "The long and winding road\n";

    // printf( "Enter a phrase: ");
    // fgets( string, sizeof phrase, stdin );

    func( phrase );

    return 0;
}
Phrase: 'The long and winding road'
Longest word: 'winding'
Phrase now: 'The long and road'

EDIT
It's better to use standard library functions than trying to reinvent available functionality (because of unfamiliarity).

The following is an even shorter version of func() above. Dealing with straggling whitespace is left as an exercise.

void func( char *phrase ) {
    char *cp = phrase, *plw = NULL;
    int lwLen = 0;

    while( *cp && *cp != '\n' ) {
        char *bp = cp += strspn( cp, " \t" ); // skip over whitespace
        cp += strcspn( cp, " \t\n" ); // skip over non-whitespace
        if( cp - bp > lwLen )
            lwLen = cp - (plw = bp);
    }
    *cp = '\0';

    printf( "Phrase: '%s'\n", phrase );
    printf( "Longest word: '%.*s'\n", lwLen, plw );
    printf( "Phrase now: '%.*s%s'\n\n", plw-phrase, phrase, plw + lwLen );
}
Fe2O3
  • 6,077
  • 2
  • 4
  • 20