Alternative Solution to the Same problem


#1

Here I use scanf and gets instead of the readline function. Also, I eliminate having to use atoi();

int main(int argc, const char * argv[]) {
    
    int x;
    char cool[30];  // character array

    printf("Where should I start counting? ");
    scanf(" %d", &x);  // capture user input into x
    
    getchar(); // capture the enter button from the buffer
    
    printf("Who is cool? ");
    gets(cool);
    
    for (int i = x; i > 0; i-=3)
    {
        if (i % 5 == 0) {
            printf("%d. Found one!\n", i);
            
        }
        else
        {
            printf("%d\n", i);
        }
    }
    return 0;
}

#2

Great job, OkayGreat!

I can see a new rising star.

However, you should ideally check the return value from scanf to ensure the variable x was assigned a value.
Also, be afraid, very afraid of the gets function.

At least:

int nc = scanf(" %d", &x);  // capture user input into x
assert (nc == 1);

Even better:

int nc = scanf(" %d", &x);  // capture user input into x
if (nc != 1) {
    // stop
    printf ("bummer: value of x is invalid!\n);
    return 1;
}

#3

Thanks. I agree. Here is some better error checking.

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

int main(int argc, const char * argv[])
{
    
    char cool[30];  // character array
    char x[6];
    int hasDigit;
    int isletters = 0;
    int num;
    
   
do {
    
    printf("Where should I start counting? ");
    scanf(" %s", x);
   
    num = atoi(x);
    
if (num != 0)
{
    hasDigit = 1;
    for (int i = num; i > 0; i -=3)
    {
        
        
             if (i % 5 == 0)
               {
                   printf("%d. Found one!\n", i);
               }
                        
               else
                 {
                  printf("%d.\n", i);
                 }
    
    }
}
    
        else
        {
            hasDigit = 0;
            printf("Please enter a number only\n\n");
            
        }

    
} while (hasDigit == 0);

do
{
    
printf("Who is cool? \n");
gets(cool);


    
    for (int i = 0; i < strlen(cool); i++)
    {
        if (isalpha(cool[i]))
            {
         
                isletters = 1;  // set flag
            }
     
        if (isspace(cool[i]))
        {
            
            isletters = 1;  // set flag
        }

        else
            {
                puts("Enter letters only");
                isletters = 0;
                break;
            }
     }

} while (isletters == 0);  // break out of loop if flag is 1

if (isletters == 1)
{
    printf("%s is cool.\n", cool);
}


return (0);

}

#4

Literally, that’s a scary piece of code!

Here is the scariest part:

char cool [30];  // character array
...
gets (cool);

What happens if gets is presented with more than 29 characters of input?

gets is an unsafe function; never use it.

If you can’t find a safer alternative, you can always write your own version of it (MyGets):

// MyGets.cc - safe gets

#include <stdio.h>

void MyGets (char *buf, long blen);

int main (int, const char *[])
{
   char buf [7];

   MyGets (buf, sizeof buf);
   printf ("--> >%s<\n", buf);

   return 0;
}

void MyGets (char *buf, long bufsize)
{
   // Read at most one less than the number of characters specified by bufsize
   // and store them in the buf and null terminate it.

   if (!(buf && bufsize > 0)) {
       return;
   }

   int x = 0;
   for (x = 0; x < bufsize - 1; ++x)
   {
      int v = getchar ();
      if (v == EOF || v == '\n') {
          break;
      }
      else {
          buf [x] = (char)v;
      }
   }
   buf [x] = 0;
}

[Become a competent programmer faster than you can imagine: pretty-function.org]


#5

Nice function. Yeah you’re right. I should of used this:

char cool[30];  // character array

printf("Who is cool? ");
fgets(cool, 30, stdin);