0

i cant get the program to properly sort the strings into largest and smallest of all the user inputs

im having issues with the if statements and how they are recording the smallest and largest

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

int main()
{
int finish = 0, longest=0, smallest=0, count =0;
char word[20], smallest_word[20], largest_word[20];
while (0 == finish)
{
    printf("enter word:");
    fflush(stdin);
    scanf("%s", &word);
    if (count == 0)
    {
        strcpy(smallest_word, word);
        strcpy(largest_word, word);
    }


    if (strcmp(word, smallest_word)<smallest)
    {
        strcpy(smallest_word, word);
        smallest = strcmp(word, smallest_word);
    }
    if (strcmp(word, largest_word) > longest)
    {
        strcpy(largest_word, word);

        longest = strcmp(word, largest_word);

    }


    if (strlen(word) == 4)
    {
        finish++;
    }
    count++;
}
printf("smallest word: %s\n", smallest_word);
printf("largest word: %s\n", largest_word);

getch();
return 0;
}

program runs just doesn't record the largest and smallest values correctly

babySteps
  • 39
  • 8
  • The C standard specifically states that: `fflush(stdin);` is undefined behavior – user3629249 Jun 19 '19 at 03:17
  • 1
    regarding: `scanf("%s", &word);` This causes the compiler to output the message: "untitled.c:13:13: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char (*)[20]’ [-Wformat=]" to fix this, use: `scanf("%s", word);` this is related to the fact that referencing an array name degrades to the address of the first byte of the array. Also, 1) always check the returned value (not the parameter values) to assure the operation was successful. Note: the `scanf()` family of functions returns the number of successful input format conversions (cont) – user3629249 Jun 19 '19 at 03:22
  • (cont) 2) when using the format specifiers '%s' and/or '%[...]' always include a MAX CHARACTERS modifier that is one less than the length of the input buffer because they always append a NUL byte to the input. This also avoids any possibility of a buffer overflow and the resulting undefined behavior. Suggest: if( scanf("%s", &word) != 1 ) { fprintf( stderr, "scanf to input word failed\n" );` Such a statement will usually be followed by 'cleanup' and `exit( EXIT_FAILURE );` – user3629249 Jun 19 '19 at 03:28
  • 1
    @user3629249 - you are right on the standard and `fflush(stdin)`, but the code contains `conio.h` - so, you can guess what MS allows as an *extension* to the C standard. See [MS-docs `fflush`](https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/fflush?view=vs-2019) – David C. Rankin Jun 19 '19 at 03:29
  • the languages 'C' and 'C++' are two different languages. Per the posted code, it is for the 'C' language, so suggest removing the 'c++' tag – user3629249 Jun 19 '19 at 03:29
  • @DavidC.Rankin, The header file: `conio.h` is not what allows the `fflush( stdin )` Rather the visual studio compiler allows it – user3629249 Jun 19 '19 at 03:31
  • The reference to `conio.h` was to imply compiling on windows (with the VS compiler, `cl.exe`) – David C. Rankin Jun 19 '19 at 03:32
  • `strcpy(smallest_word, word); smallest = strcmp(word, smallest_word); }` is same as `strcpy(smallest_word, word); smallest = 0; }` – chux - Reinstate Monica Jun 19 '19 at 03:32
  • babySteps, Post input used, output seen and expected. Without that, your post is unnecessarily unclear. – chux - Reinstate Monica Jun 19 '19 at 03:37
  • bruh this is semantics, i need help with the actual logic of the program @everyone – babySteps Jun 19 '19 at 03:37
  • on stackoverflow.com. when asking a question about a run time problem, as this code is doing, you need to post a [mcve] Otherwise the question is 'off topic'. So it is not 'semantics' but rather a requirement of the web site – user3629249 Jun 19 '19 at 03:41
  • regarding: `count++;` This is executed every time through the loop, so in ~2gig words it will overflow. in C, overflow of a signed integer is undefined behavior. Lets' not take that risk. Suggest moving that statement to inside the `if()` that checks if the variable is 0 – user3629249 Jun 19 '19 at 03:53
  • can anyone help? – babySteps Jun 19 '19 at 04:40

4 Answers4

1

Both your logic and syntax have some problems.

Here strcmp(src,dst) returns 0 if both strings are same else some positive or negative number when src>dst and dst>src respectively.

And scanf() needs address of variable and array name itself gives the address of 1st element of the array so no need of using '&'.

And for logic part, you should continue the loop after increasing the value to avoid extra confusion and comparisons.

  if (count == 0)
{
    strcpy(smallest_word, word);
    strcpy(largest_word, word);
}

And there is no need of variables longest and smallest as instead of them both you can use zero.

The completely working code I edited for you is

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

int main()
{
int finish = 0, longest=0, smallest=0, count =0;
char word[20], smallest_word[20], largest_word[20];
while (0 == finish)
{
    printf("enter word:\t");
    scanf("%s", word);
    if (count == 0)
    {
        strcpy(smallest_word, word);
        strcpy(largest_word, word);
        count++;
        continue;   //To ensure in first time loop ends here 
    }


    if (strcmp(word, smallest_word)<0)
        strcpy(smallest_word, word);
    else if (strcmp(word, largest_word) > 0)
        strcpy(largest_word, word);



    if (strlen(word) == 4)
    {
        finish++;
    }
    count++;
}
printf("smallest word: %s\n", smallest_word);
printf("largest word: %s\n", largest_word);

getch();
return 0;
}

Screenshot of output ::

Happy Coding :)

Rishabh Ryber
  • 446
  • 1
  • 7
  • 21
0

regarding:

if (strcmp(word, smallest_word)<smallest)

and

if (strcmp(word, largest_word) > longest)

strcmp() returns 0 or >0 or <0. It does not return a pointer to anything. a returned value <0 indicates that the first parameter comes alphabetically before the second parameter. A returned value of 0 indicates the two parameters are equal. A returned value of >0 indicates the first parameter comes alphabetically after the second parameter.

user3629249
  • 16,402
  • 1
  • 16
  • 17
  • doesnt help much – babySteps Jun 19 '19 at 04:40
  • neither the OPs code nor my answer are actually trying to sort the strings. They are only trying to determine which string is earliest (and latest) alphabetically The main problem with the OPs code is trying to compare the return value from `strcmp()` to anything other than > 0, =0, <0 – user3629249 Jun 20 '19 at 04:40
0

You can see the size of a string using strlen() from string.h library.

0

The header file conio.h and its getch() are not part of standard C and you should probably avoid using them.
See Why is getch not portable? and Why must we refrain from using conio.h? Is it obsolete?.


Your loop seem to go on till the user enters a word of length exactly 4. No need to use a separate variable like finish for it. Just use a break statement.
ie, instead of

if (strlen(word) == 4)
{
    finish++;
}

do

if (strlen(word) == 4)
{
    break;
}

and you can get rid of that finish variable.


scanf() expects pointers to buffers where the scanned input need be stored as parameters after the format string. With

scanf("%s", &word);

you are giving pointer to a pointer as word itself is a pointer since array names in C decay into pointers to their first element. So word by itself points to the first character stored in the word[] array.

Use

scanf("%19s", &word);

instead. 19 is the width specifier. 19 was chosen since the size of word is 20 and we need 1 character space to store the \0 denoting the end of string. This can help avoid buffer overflow.

You may also want to check the return value of scanf(). It returns the number of successful assigments like

if( scanf("%19s", &word)!=1 ) {
    //Something went wrong.
}

See What happens if I use "&" with string in scanf function?.


Usage of fflush() on stdin leads to undefined behaviour in C as it is meant to be used only on output streams. See Using fflush(stdin).


strcmp() just returns a negative number if the first argument is lesser than the second and a positive number if first argument is greater than the other. These numbers could be anything. You need not save the return value of strcmp().

So instead of

if (strcmp(word, smallest_word)<smallest)
{
    strcpy(smallest_word, word);
    smallest = strcmp(word, smallest_word);
}
if (strcmp(word, largest_word) > longest)
{
    strcpy(largest_word, word);
    longest = strcmp(word, largest_word);
}

do

if (strcmp(word, smallest_word) < 0)
{
    strcpy(smallest_word, word);
}

if (strcmp(word, largest_word) > 0)
{
    strcpy(largest_word, word);
}

So, you could change the program to

char word[20], smallest_word[20], largest_word[20];
for(int count=0; ; ++count)
{
    printf("enter word:");
    scanf("%19s", word);
    if (count == 0)
    {
        strcpy(smallest_word, word);
        strcpy(largest_word, word);
    }

    if (strcmp(word, smallest_word) < 0)
    {
        strcpy(smallest_word, word);
    }

    if (strcmp(word, largest_word) > 0)
    {
        strcpy(largest_word, word);
    }

    if (strlen(word) == 4)
    {
        break;
    }
}
printf("smallest word: %s\n", smallest_word);
printf("largest word: %s\n", largest_word);
J...S
  • 5,079
  • 1
  • 20
  • 35