1

I know this is a cheesy question but I can not figure it out what's happening here...If you delete the last loop, problem will be solved. It just happens when "." is the first input...why?

#include <stdio.h>
#include <conio.h>
int main()
{   
    long int fact;
    int i=1, num, num0,per;
    char end;
    for(num0=0; (end=getchar())!=46; num0++){ 
        printf("\nEnter a number:");
        scanf("%d",&num);
        fact=1;
        for(; i<=num; i++){
            fact*=i;
            fact+=1;
            fact+=num;
            printf("Ok done");
        }
        printf("The factorial is:%ld",fact);//*
        printf("Hi");
    }
        for(per=0; per<=10 ;per++)//*
        printf("per");//*

    printf("Finish\n");
    getch(); 
    return 0;
}

Input:

 Enter a number:.

Output:

 Ok doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneOk doneThe factorial is:-1271807075HiperperperperperperperperperperperFinish
dbenham
  • 127,446
  • 28
  • 251
  • 390
Benjamin
  • 25
  • 7
  • 1
    I get "perperperperperperperperperperperFinish" as output if I enter a period ("."). – NXP5Z Sep 21 '20 at 12:11
  • Also, what is this: ```fact+=1; fact+=num;```? – NXP5Z Sep 21 '20 at 12:15
  • @NXP5Z You should enter "." for the second input...i said first because i consider the first is when the code goes into a loop and ask you "Enter a number"...and that's just a formula – Benjamin Sep 21 '20 at 12:26
  • If you enter `.` after you get output `Enter a number`, your input will be parsed by `scanf` which will not be able to read an integer. You should check return value of `scanf`. – Gerhardh Sep 21 '20 at 12:53

3 Answers3

1

Here is a cleaner version. If you enter "s" when it prompts for the number, the program will quit. If you enter anything else it will advance its computation. Be aware that your factorial is wrong, but I left it because I am not sure what you want to calculate.

#include <stdio.h>
#include <conio.h>
int main()
{   
    long int fact = 0;
    int num = 0;
    char stop;

    while(1) {
        printf("\nEnter s to quit, any other char to continue\n");
        scanf("%c", &stop);
        if(stop == 's') {
            printf("Finish\n");
            return 0;
        } else {
            printf("\nEnter a number: ");
            scanf("%d", &num);
            
            fact = 1;
            for(int i = num; i > 0; i--){
                fact *= i;
                fact += 1;
                fact += num;
            }
            printf("\nThe factorial is: %ld \n", fact);
        }
    }

    return 0;
}

EDIT:

One of the problems is that you use num uninitialized, and when you enter a period, scanf doesn't pick it up. Therefore, some garbage value remains in the unitialized num, giving you the output you did not expect. When you leave the "per"-loop out, for some reason, num is initialized to 0. So your program doesn't enter the loop, because i is bigger than num. This is pure coincidence. The connection between the loops is the initialization of the variables.

NXP5Z
  • 173
  • 7
  • 1
    Sorry for my unclear code, but i just want to know why my output is that and also why if i delete the last loop it'll work properly. I can't understand the relation between them. – Benjamin Sep 21 '20 at 12:49
  • I have solved your problem - the relation between the loops was the initialization. Do you have further questions? – NXP5Z Sep 21 '20 at 17:44
  • 1
    The problem was solved, but I’m still wondering what the the “some reason” is. Do you know any resource that i learn more about that? And thanks for your help. – Benjamin Sep 22 '20 at 11:48
  • If you're interested, I would highly recommend that you look at the values in your program while it's running (i.e. debugging). For simple programs like this I recommend OnlineGDB, so you can use it on windows hassle-free. As for initialization: AFAIK, the values you get for unitialized variables might as well be explained by magic; I don't think it follows any predictable pattern. *Never* assume anything about such variables. – NXP5Z Sep 22 '20 at 12:15
0

It seems there is a conversion from the character you give as input to its ascii code (46, in case of ‘.’).

Maybe the problem is that there is an overflow with your algorithm and “long” digits (46, for example). Try to use an other data type to save longer digits.



UPDATE

In C, scanf doesn't autoconvert characters to ascii code, so, as you haven't typed a digit as input where it is expected, the "garbage" value (which is a long digit) from num is getted. Instead, try to initialize num to -1 (just because of maths, (-1)! doesn't exist) at the time you declare it.

int main ()
{
  long int fact;
  int num = -1;
  char end;

  for (int num0 = 0; (end = getchar ()) != 46; num0++)
    {
      printf ("\nEnter a number:");
      scanf ("%d", &num);

      fact = num >= 0 ? 1 : 0; // 0 is a good value to a non valid entry for the factorial, as the factorial of valid entries will never be 0

      // If the factorial was zero, then the factorials for all number will be the same,
      // something which is impossible.
      if (fact > 0)
        {
          for (int i = 1; i <= num; i++)
            {
              fact *= i;
              fact += 1;
              fact += num;
              printf ("Ok done");
            }

          printf ("The factorial is: %ld", fact);   //*
        }
    
      printf ("Hi");
    }


    for (int per = 0; per <= 10; per++) //*
      printf ("per");       //*


    printf ("Finish\n");
    getch ();
    return 0;
}

Also, with this solution you will solve the problem you have when you give negative numbers as input. (Factorial of negatives don't exist)



But also, I see this kinda strange, maybe some rare stuff from C, not sure, but if you type ‘.’ the first time, it shouldn’t appear the text ‘enter a number’ as in a for loop the condition runs before the local scope (the set of statements on its body)...

I have tested your code on my compiler and when I type '.' in the first input, the loop statements doesn't run, as expected.

So, if I type '.' in the "Enter number" input, I get an overflow (the unexpected non-positive long integer which represents it), and that is because of what I said avobe. You can also try to type 46 in the second input (not in the getchar)

Victor Molina
  • 2,353
  • 2
  • 19
  • 49
0

Your actual error is located on this line:

       scanf("%d", &num);

If scanf encounters a "." instead of an integer, it will fail, leaving num unassigned. In your case, num is assigned a random value, which seems to be different depending on the rest of your code. (undefined behavior)

Modify your code to handle the case where scanf doesn't parse any input, by replacing the scanf line with a check on the return value of scanf:

        if (scanf("%d", &num) <= 0) /* invalid input */
            continue; /* Or perhaps "break" if you want to cancel on this condition */

See for more info on scanf: https://en.cppreference.com/w/c/io/fscanf

Elijan9
  • 1,269
  • 2
  • 17
  • 18