Search code examples
cfor-loopmultidimensional-arrayc-stringsstrlen

Include spaces when counting the length of a string


Im trying to create a simple program that reads strings entered by the user and displays the longest and shortest string. The program works fine for single words such as 'dog' or 'cat' but if I was to type 'rattle snake' it takes it as two individual words 'rattle' and 'snake' and not one whole string with a space included. Is there any reason why its registering the space as a divider/separator and not treating it as one whole string? Thank you!

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

int main()
{
//DEFINE VALUES N & I COUNTERS
//DEFINE VALUES FOR MAX AND MIN INDEX POINTERS
//DEFINE WORD LENGTH ARRAY
//DEFINE MAX AND MIN LENGTH VALUE VARIABLES USING STRLEN FUNCTION
int n,i;
size_t maxIndex=0;
size_t minIndex=0;
char word_length[2][20];
size_t maxLength =strlen(word_length[0]);
size_t minLength =strlen(word_length[0]);
    /*USER ENTERS LIST LENGTH*/
    printf("How many items are in your list?\n");
    scanf("%d",&n);
    
    /*USER ENTERS THE WORDS ONE AFTER ANOTHER USING THE ENTER BUTTON*/
    printf("Please enter a list of words \n ---------------------\n");
    

    /*SEARCH FROM INDEX POINTER 0-LENGTH OF LIST*/
    for (size_t i=0;i<n;i++)
    {
        /*CALCULATE THE LENGTH OF EACH WORD AND STORE IT IN WORD LENGTH ARRAY*/
        scanf("%19s",word_length[i]);
        /*NEW VARIABLE LENGTH IS UPDATED TO LENGTH OF EACH STRING HELD IN EACH POINTER IN WORD_LENGTH ARRAY*/
        size_t length = strlen(word_length[i]);
        /*IF THE NEW LENGTH IS BIGGER THAN THE PREVIOUS MAXIMUM LENGTH, THE MAXIMUM LENGTH SCORE IS UPDATED*/
        /*THE MAXINDEX VARIABLE KEEPS A RECORD OF WHICH ARRAY POSITION THIS STRING IS HELD IN*/
        /*THE SAME HAPPENS FOR THE MIN LENGTH ARRAY*/
        if (maxLength<length) {
            maxLength = length;
            maxIndex = i;
        }
        else if (length<minLength){
            minLength=length;
            minIndex=i;
        }
    }
    

    /*THE BIGGEST WORD IS DISPLAYED ON SCREEN USING THE MAXINDEX POINTER*/
    /*THE SMALLEST WORD IS DISPLAYED ON SCREEN USING THE MAXINDEX POINTER*/
    printf("\nThe biggest word is '%s' with %zu characters\n",word_length[maxIndex],strlen(word_length[maxIndex]));
    printf("'%s' is stored in position %zu \n",word_length[maxIndex],maxIndex);
    printf("\nThe smallest word is '%s' with %zu characters\n",word_length[minIndex],strlen(word_length[minIndex]));
    printf("'%s' is stored in position %zu \n",word_length[minIndex],minIndex);

return 0;
}

Solution

  • For starters these declarations

    size_t maxLength =strlen(word_length[0]);
    size_t minLength =strlen(word_length[0]);
    

    invoke undefined behavior because the array word_length is not initialized

    char word_length[2][20];
    

    You need to initialize it as for example

    char word_length[2][20] = { '\0' };
    

    To read a string with embedded spaces you can use the following call of scanf

    scanf(" %19[^\n]",word_length[i]);
    

    Also pay attention to that you declared an array of two elements

    char word_length[2][20];
    

    but you are using a for loop with n iterations

    for (size_t i=0;i<n;i++)
    {
        /*CALCULATE THE LENGTH OF EACH WORD AND STORE IT IN WORD LENGTH ARRAY*/
        scanf("%19s",word_length[i]);
        //...
    

    that again can invoke undefined behavior.

    You need to introduce one more character array as for example

    char word[20];
    

    and read strings in the for loop in this array.

    The program can look for example the following way

    #include <stdio.h>
    #include <string.h>
    
    int main( void )
    {
        enum { M = 2, N = 20 };
        enum { MIN = 0, MAX = 1 };
    
        char min_max_word[M][N];
        size_t min_max_length[M] = { 0, 0 };
        size_t min_max_index[M] = { 0, 0 };
    
        size_t n = 0;
    
        printf( "How many items are in your list? " );
        scanf( "%zu", &n );
    
        size_t i = 0;
    
        for ( char word[N]; i < n && scanf( " %19[^\n]", word ) == 1; i++ )
        {
            size_t length = strlen( word );
    
            if ( i == 0 )
            {
                strcpy( min_max_word[MIN], word );
                min_max_length[MIN] = length;
                min_max_index[MIN] = i;
    
                strcpy( min_max_word[MAX], word );
                min_max_length[MAX] = length;
                min_max_index[MAX] = i;
            }
            else if ( length < min_max_length[MIN] )
            {
                strcpy( min_max_word[MIN], word );
                min_max_length[MIN] = length;
                min_max_index[MIN] = i;
            }
            else if ( min_max_length[MAX] < length )
            {
                strcpy( min_max_word[MAX], word );
                min_max_length[MAX] = length;
                min_max_index[MAX] = i;
            }
        }
    
        if (i != 0)
        {
            printf( "\nThe biggest word is '%s' with %zu characters\n", min_max_word[MAX],  min_max_length[MAX] );
            printf( "'%s' is stored in position %zu \n", min_max_word[MAX], min_max_index[MAX] );
            printf( "\nThe smallest word is '%s' with %zu characters\n", min_max_word[MIN], min_max_length[MIN] );
            printf( "'%s' is stored in position %zu \n", min_max_word[MIN], min_max_index[MIN] );
        }
    }
    

    The program output might be

    How many items are in your list? 5
    1
    12
    123
    1234
    12345
    
    The biggest word is '12345' with 5 characters
    '12345' is stored in position 4
    
    The smallest word is '1' with 1 characters
    '1' is stored in position 0