0

I hope you are doing well everyone. I was given this homework by my teacher.

Which is the problem below:

Write a program that will ask for n positive whole numbers. Your program will only stop asking for a number if the input number is 0 or < 0. From these inputs, determine all the prime numbers. After determining the prime numbers, write a menu option shown below:
                
            [A] Display One’s   
            [B] Display Ten’s 
            [C] Display Hundred’s 
            [D] Display Thousand’s 

    If the user presses on of these options, then it will display what is being asked. To further understand and shorten the instructions, an illustration is provided below.

Input numbers: 123, 112, 1377, 2, 13, 0
Prime numbers: 123 1377 2 13
If the user presses ‘A’, then the output is
        123     = 3
        1377    = 7
        2   = 2
        13  = 3
If the user presses ‘B’, then the output is
        123 = 23
        1377    = 77
        2   = 0
        13  = 13
If the user presses ‘C’, then the output is
        123 = 123
        1377    = 377
        2   = 0
        13  = 0
If the user presses ‘D’, then the output is
        123 = 0
        1377    = 1377
        2   = 0
        13  = 0


I've written a program that I thought would solve the problem, but somehow after I input a character (A,B,C,D) the program immediately terminates? If someone could point any other mistakes or have any suggestions in mind. I'll be open to them and I'll be grateful. Thanks so much in advance. :))

#include<stdio.h>

int isPrime(int num);
void Sort(char sort, int psize, int* prime);

int main ()
{
    int psize=0;
    int i, num=1;
    int arr[1000], prime[1000];
    char sort;

    do
    {
        printf("Enter array element:");
        scanf("%d", &num);

        if(num<=0) break;

        if(isPrime(num))
        {
            prime[psize]= num; //assign to prime array if it is a prime
            psize++;
        }

    } while(num>0);

    printf("\nEnter [A] to Display One's\nEnter[B] Display Ten's\nEnter[C]Display Hundred's\nEnter[D]Display Thousand's");

    scanf("%c", &sort);

    Sort(sort, psize, prime);

}

int isPrime (int num)
{
  int i, flag=1;
  for(i=2;i<num;i++)
   {
    if(num%i==0)
      {
       flag=0;
       break;
      }
   }
   return flag;
}

void Sort(char sort, int psize, int* prime)
{
    int i, ans;

    if(sort == 'A'){
        printf("Ones\n");
        for(i=0;i<psize;i++)
        {
            ans = prime[i] % 10;
            printf("%d = %d\n", prime[i], ans);
        }
    }

    else if(sort == 'B'){
        printf("Tens\n");
        for(i=0;i<psize;i++)
        {
            if(prime[i] >= 10)
            ans = prime[i] % 100;
            else
            ans = 0;
            printf("%d = %d\n", prime[i], ans);
        }
    }

    else if(sort == 'C'){
        printf("Hundreds\n");
        for(i=0;i<psize;i++)
        {
            if(prime[i] >= 100)
            ans = prime[i] % 1000;
            else
            ans = 0;
            printf("%d = %d\n", prime[i], ans);
        }
    }
    else if(sort == 'D'){
        printf("Thousands\n");
        for(i=0;i<psize;i++)
        {
            if(prime[i] >= 1000)
            ans = prime[i] % 10000;
            else
            ans = 0;
            printf("%d = %d\n", prime[i], ans);
        }
    }

}


Kristofer
  • 21
  • 2
  • 1
    Please see [scanf() leaves the newline char in the buffer](https://stackoverflow.com/questions/5240789/scanf-leaves-the-new-line-char-in-the-buffer). The `scanf` conversion stops at the first character it cannot convert, which is typically (but not necessarily) a space or a newline, and that character remains in the input buffer. It will be read by the *next* `scanf()`. Format specifiers `%d` and `%s` and `%f` automatically filter such leading whitespace characters, but `%c` and `%[]` and `%n` do not. You can instruct `scanf` to do so by adding a space before `%`. So `scanf(" %c", &sort);`. – Weather Vane May 24 '21 at 19:23
  • 1
    The `scanf()` family are not simple functions, but the student comes up to them very soon. I recommend spending at least an hour with the man page and a little test program. – Weather Vane May 24 '21 at 19:27
  • 1
    Notice too that the `Sort()` function has no rearguard action to take care of the value passed not being one of the four expected values, such as `else printf("Invalid entry\n");` Catching unexpected input is what can make a vulnerable program more robust. – Weather Vane May 24 '21 at 19:30
  • Your suggestion immediately solved the problem I had with the code. Thanks so much for your response. :)) – Kristofer May 25 '21 at 07:17

1 Answers1

-2

I think that will help you out. put a fflush() after your scanf function like:

scanf("%d", &num);
fflush(stdin);

Or you use a easier way

int getNumber()
{
    char userinput = '1';
    int number = 0;
    /*
        Ascii-table
        0 = 48
        1 = 49
        ...
        9 = 57
    */
    while(1)
    {
      userinput = getchar();
      if (userinput == '\n') break;
      if (userinput >= 48 && userinput <= 57)
         number = (number * 10) + (userinput - 48);
    }
    
    return number;
}

Replace your scanf("%d", &num); with num = getNumber(); - that works!

So, here another code with A-D letters

I hope this will be enough now - And all useres forgive me for my uncomplete code review ^^" :

int getNumber( int opt )
{
    char userinput = '1';
    int number = 0;
    /*
        Ascii-table
        0 = 48
        1 = 49
        ...
        9 = 57
    */
    while(1)
    {
      userinput = getchar();
      if (userinput == '\n') break;
      
      /*
        opt (Options)
            1: Numbers
            2: Letters A-D
            Other numbers undefined!
      */
      switch(opt)
      {
        case 1:
            /* Only 0-9 allowed */
            if (userinput >= 48 && userinput <= 57)
                number = (number * 10) + (userinput - 48);
        break;
        case 2:
            /* Only A-D allowed */
            if (userinput >= 'A' && userinput <= 'D')
                number = userinput;
        break;
        default:
            /* Nothing to do - wrong input */
            number = 0; 
        break;
      }
      
    }
    
    return number;
}

Replace your scanf("%d", &num); with num = getNumber(1);

Replace your scanf("%d", &sort); with sort = getNumber(2);

  • 1
    I am sorry but that is **undefined behaviour** on an input stream. The `scanf` function is designed to deal with the problem without any work-arounds. – Weather Vane May 24 '21 at 19:35
  • Now, the code is correct. sorry. I forgot something. I think with that function you have a better way as scanf. – MitnickCodeHelper May 24 '21 at 19:58
  • 1
    `scanf()` is provided so we don't have to write non-portable code such as this, but it's not inputting an integer value that OP is having trouble with, but the *following* character `'A'` etc. – Weather Vane May 24 '21 at 20:00
  • @WeatherVane I change the position of the check. Now only numbers are allowed! – MitnickCodeHelper May 24 '21 at 20:06