# Thread: segmentation fault (if input == var) program compiles

1. ## segmentation fault (if input == var) program compiles

Hey all, this exercise is out of "Beginning C 5th Edition" and it's much easier than working through the Project Euler problems but I am still working on them too. Here is the exercise question:

"The logic of the program is quite straightforward. The program must generate a sequence of integers between 0 and 9 and display the sequence on the screen for one second before erasing it. The program should then read the player’s pathetic attempt to enter the identical sequence of digits. If the player is lucky enough to get the sequence correct, the computer should repeat with another sequence of the same length. If the player’s luck holds out for three successive sequences of a given length, the program should continue by displaying a longer sequence for the player to try. This continues until the player’s luck runs out and he or she gets a sequence wrong. The program will then calculate a score based on the number of successful tries and the time taken and invite the player to play again."

Please, I am getting Segmentaton Fault but program runs fine but cannot get a successful entry to see if there was a match for the scanf entry. This if() statement:

Code:
`        if (input == num)`
again, this exercise was much easier than the project euler problems but it is preparing me for them (this exercise came out of a chapter on Loops and it's good to freshen up on the nested for loops for the project euler problems) and I haven't even touched K&R yet.

Code:
```/* Chapter 4 Exercise from C Programming book 2/14/2020 */

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

void delay (int seconds)     // delay function i got this source code from google
{
unsigned long int count=333333333, i, j;

for(i = 0;i<seconds;i++)
for(j = 0; j < count; j++);
}

int main (void)
{

int limit = 9;
int count, num = 0;
char c = 'X';
int i;
int input = 0;
char newgame;
time_t t;
srand((unsigned) time(&t));

// output text %d\t
for (;;)         // game loop
{
printf("\n");

for (count = 1; count <= 9; count++)      // generate random number loop digit from 0 -> 9
{
num = rand() % limit;
printf("%d", num);
}

printf("\n");

delay(1);     // create 1 second program delay before clear screen with 'X's

// clear screen with x's
for (int ctr_1 = 1; ctr_1 < 7500; ctr_1++)
{
printf("%c", c);
}

printf("\n\n");

printf("What sequence was inserted?: ");
scanf("%d", input);

if (input == num)  // corrected answer was inserted
{
// go back to beginning of program for 3 times
/*
for (i = 1; i < 3; i++) // loop for correct answer for 3 times & increase sequence length if true three times
{
;
}
*/
}

{
// new games? Yes or no (tolower)
/*
printf("Do you want a new game? (Y or N)\n");
scanf("%c", newgame);

if(tolower(newgame) == 'n') // look for any sign of no (not case sensitive)
{
return 0;
//exit(1);     // do this...
}

else     // 'y' was inserted
{
// start new game
}
*/
printf("\nError!\n");
}
}

return 0;
}``` 2. Seriously, compile with warnings and fix them before running code.
Code:
```\$ gcc -Wall foo.c
foo.c: In function ‘main’:
foo.c:63:15: warning: format ‘%d’ expects argument of type ‘int *’, but argument 2 has type ‘int’ [-Wformat=]
scanf("%d", input);
^
foo.c:26:10: warning: unused variable ‘newgame’ [-Wunused-variable]
char newgame;
^
foo.c:24:9: warning: unused variable ‘i’ [-Wunused-variable]
int i;
^
\$```
> if (input == num)
No, it's the completely borked scanf attempt which fails to pass a pointer which generates the actual fault.

And even if you get no warnings, you do this.
Run the code in the debugger, and it will tell you exactly the line where the problem originated.
Code:
```\$ gcc -g -Wall foo.c
\$ gdb -q ./a.out
(gdb) run
<<snipped>>
What sequence was inserted?: 333333

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7a6cde5 in _IO_vfscanf_internal (s=<optimised out>, format=<optimised out>, argptr=argptr@entry=0x7fffffffdd58, errp=errp@entry=0x0) at vfscanf.c:1902
1902	vfscanf.c: No such file or directory.
(gdb) bt
#0  0x00007ffff7a6cde5 in _IO_vfscanf_internal (s=<optimised out>, format=<optimised out>, argptr=argptr@entry=0x7fffffffdd58, errp=errp@entry=0x0) at vfscanf.c:1902
#1  0x00007ffff7a785df in __isoc99_scanf (format=<optimised out>) at isoc99_scanf.c:37
#2  0x000000000040081d in main () at foo.c:63
(gdb) frame 2
#2  0x000000000040081d in main () at foo.c:63
63	        scanf("%d", input);``` 3. ## I ran the code through gdb couldn't make sense out of it, complained about line 13 though and kept showing random numbers Originally Posted by Salem Seriously, compile with warnings and fix them before running code.
Code:
```\$ gcc -Wall foo.c
foo.c: In function ‘main’:
foo.c:63:15: warning: format ‘%d’ expects argument of type ‘int *’, but argument 2 has type ‘int’ [-Wformat=]
scanf("%d", input);
^
foo.c:26:10: warning: unused variable ‘newgame’ [-Wunused-variable]
char newgame;
^
foo.c:24:9: warning: unused variable ‘i’ [-Wunused-variable]
int i;
^
\$```
> if (input == num)
No, it's the completely borked scanf attempt which fails to pass a pointer which generates the actual fault.

And even if you get no warnings, you do this.
Run the code in the debugger, and it will tell you exactly the line where the problem originated.
Code:
```\$ gcc -g -Wall foo.c
\$ gdb -q ./a.out
(gdb) run
<<snipped>>
What sequence was inserted?: 333333

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7a6cde5 in _IO_vfscanf_internal (s=<optimised out>, format=<optimised out>, argptr=argptr@entry=0x7fffffffdd58, errp=errp@entry=0x0) at vfscanf.c:1902
1902    vfscanf.c: No such file or directory.
(gdb) bt
#0  0x00007ffff7a6cde5 in _IO_vfscanf_internal (s=<optimised out>, format=<optimised out>, argptr=argptr@entry=0x7fffffffdd58, errp=errp@entry=0x0) at vfscanf.c:1902
#1  0x00007ffff7a785df in __isoc99_scanf (format=<optimised out>) at isoc99_scanf.c:37
#2  0x000000000040081d in main () at foo.c:63
(gdb) frame 2
#2  0x000000000040081d in main () at foo.c:63
63            scanf("%d", input);```
Thanks Salem for the post. Look at this code (this program finds a succesful match for '10' inserted

Code:
```#include <stdio.h>

int main()
{
int a = 10;
int b;

printf("Insert number: ");
scanf("%d", &b);

if(b == a)
{
}

else
{
printf("Error, no match\n");
}

return 0;
}```
Here's my code again that Salem commented on, with a few commented out additions. I'm not getting correct program output for if (input == num). Also, Salem, I reviewed your comment about running cc (gcc) with -Wall switch (I am on Debian Linux) and I believe it is now time to use gdb I have been using C + vim + cc for 2 years Thanks for finding the above typo, the missing '&' on the &input for scanf() function. Please, what am I missing in comparing my code to these two programs?

Code below, similar if statement functions, program not finding match (always returning "else" function)

Code:
```/* Chapter 4 Exercise from C Programming book 2/14/2020 */

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

void delay (int seconds)     // delay function i got this source code from google
{
unsigned long int count=333333333, i, j;

for(i = 0;i<seconds;i++)
for(j = 0; j < count; j++);
}

int main (void)
{

int program_execution = 0;
int game_loop = 0;
int limit = 9;  // max digits to generate for random number
int count, num = 0;
char c = ' ';  // fill console with blank space to clear screen
int input;
time_t t;
char newgame;
int successful_tries = 0;
srand((unsigned) time(&t));

for(;;)
//for ( ; game_loop > 0; --game_loop) // count down how many tries left until program ends
{
printf("\n");

for (count = 1; count <= 9; count++)      // generate random number loop digit from 0 -> 9
{
num = rand() % limit;
printf("%d", num);
}

printf("\n");

delay(1);     // create 1 second program delay before clear screen with 'X's

// clear screen with x's
for (int ctr_1 = 1; ctr_1 < 7500; ctr_1++)
{
printf("%c", c);
}

printf("\n\n");

printf("What sequence was inserted?: ");
scanf(" %d", &input);

if (input == num)  // corrected answer was inserted, increase sequence length. Go to beginning of progrem (program_begin--), sequence_length++);
{
/*
while (input == num)
{
printf("Do you want a New Game? (Y or N)\n");
scanf("%c", &newgame);
if(tolower(newgame) == 'y') // look for any sign of no (not case sensitive)
{
break;
}

else
{
printf("Error!\n");
}
}
*/
}

else
{
//++successful_tries;
printf("Error, Not Correct!\n");
}
}
}

// The program will the calculate a score based on the number of successful tries and the time taken and invite the player to play again.

//printf("You had %d successful try. Program execution took %d seconds.\n", successful_tries, program_execution);``` 4. Hey all, i believe the scanf() function is getting confused with a for loop or the delay() function resulting in a confused scanf() function, resulting in there being no exact match for the if (input==num) function, therefor it always goes to else, even when an exact 9 sequence match is typed in. I was wondering if something like this would help, as i've used this before on another program, but someone later said it wasn't completely 100% correct.

Code:
`while((getchar()) != '\n');` 5. Code:
```        for (count = 1; count <= 9; count++)      // generate random number loop digit from 0 -> 9
{
num = rand() % limit;
printf("%d", num);
}```
The code above is only storing one random number (digit) between 0 and 9. E.g. if this produces the sequence 1 2 3 4 5 6 7 8 9 then the user has to enter 9 for the input == num condition to be true.

As for the delay function... I doubt that's doing anything at all and if you turn on optimisation (e.g. compile with, say, -O2 using gcc) then the compiler will optimise the loops away as dead code 6. Thanks for the followup Hodor, I misread the Exercise question. Looks like the book wasn't asking for a 9 digit number, that would be beyond my capabities and isn't mentioned in the Chapter, also I have removed the for loop and added this:

Code:
```srand(time(NULL));
num = 1 + rand() % limit;```
this now makes the code easier to work with Originally Posted by Hodor Code:
```        for (count = 1; count <= 9; count++)      // generate random number loop digit from 0 -> 9
{
num = rand() % limit;
printf("%d", num);
}```
The code above is only storing one random number (digit) between 0 and 9. E.g. if this produces the sequence 1 2 3 4 5 6 7 8 9 then the user has to enter 9 for the input == num condition to be true.

As for the delay function... I doubt that's doing anything at all and if you turn on optimisation (e.g. compile with, say, -O2 using gcc) then the compiler will optimise the loops away as dead code 7. This is what I came up with...there are a few bugs, and i'll work on it more tomorrow. Any suggestions running it through gdb? That's my next step, using gdb.

Code:
```/* Chapter 4 Exercise from C Programming book 2/14/2020 */

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

void delay (int seconds) 	// delay function i got this source code from google
{
unsigned long int count=333333333, i, j;

for(i = 0;i<seconds;i++)
for(j = 0; j < count; j++);
}

int main (void)
{

int game_loop = 3;
char c = ' ';  // fill console with blank space to clear screen
int successful_tries = 0;
char newgame = 0;
int num = 0;
int input = 0;
int limit = 9;
int limit_2 = 1;

printf("This is a game to test your memory, with a random number of 1 digit that will be displayed a max of 3 successive times.\n");
clock_t t;
t = clock();
//for (;;)
for ( ; game_loop > 0; --game_loop) // count down how many tries left until program ends
{
// code to compute random digits
srand(time(NULL));
num = limit_2 + rand() % limit;

printf("\n");

printf("%d", num);

delay(1); 	// create 1 second program delay before clear screen with 'X's

// clear screen with x's
for (int ctr_1 = 1; ctr_1 < 7500; ctr_1++)
{
printf("%c", c);
}

printf("\n\n");

printf("\nYou have %d tr%s left.\n", game_loop, game_loop == 1 ? "y" : "ies");
printf("What sequence was displayed?: ");
scanf("%d", &input);

if (input == num) // corrected answer was inserted, increase sequence length. Go to beginning of progrem (program_begin--), sequence_length++);
{

int i = 0;

// where's score variable

while (i < 1)  // per one match (one correct match)
{
successful_tries += 1; // Successful tries for end of program
++i;
}

if (successful_tries == 3) // sequence was inserted 3 times in a row
{
limit += 191; // make sequence 3 digits
limit_2 += 49;  // limit_2 = limit_2 + 49;
}

if (successful_tries >= 3) // if successful_tries is greater than or equal to 3
{
game_loop += 1; // increment game_loop + 1 infinitely
}
}

else if (input != num)
{
printf("Do you want a New Game? ('n' to Exit)\n");
scanf("%c", &newgame);
while ((getchar()) != '\n');
if(newgame == 'n')
{
exit(1);
}

else if (newgame == 'y')
{
break;
}
}
}

// The program will then calculate a score based on the number of successful tries and the time taken and invite the player to play again.
t = clock() - t;
double program_execution = ((double)t)/CLOCKS_PER_SEC; // in seconds
printf("You had %d successful tr%s. Program execution took %f seconds.\n", successful_tries, successful_tries == 1 ? "y" : "ies", program_execution);

return 0;
}``` 8. Please help, wouldn't mind a few suggestions, I know I could just sit here and play with the loops, the whole chapter is on loops (Chapter 4), but I was thinking, is this correct:

Code:
```		else if (input != num)
{
printf("Do you want a New Game? ('n' to Exit)\n");
scanf("%c", &newgame);
while ((getchar()) != '\n');
if(newgame == 'n')
{
exit(1);
}

else if (newgame == 'y')```
My book mentions using "break" to break out of the loop (code mentioned above is two nested else if statements), inserting a 'y' for the else if statement isn't working in the program unless successive_tries is >= 3

Is this correct, an if() statement, or would a while loop work? How about while (input != num) ?
Code:
`if (input == num)`
should be a while loop 9. This code works, this just about finishes the first part of the exercise. I removed the if() and else if() statements inside the else if () statement under the matching (input != num) which was causing the 'break' keyword to not work. A pretty basic exercise. Look forward to working through the rest of it
Code:
```/* Chapter 4 Exercise from C Programming book 2/14/2020 */

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

void delay (int seconds) 	// delay function i got this source code from google
{
unsigned long int count=333333333, i, j;

for(i = 0;i<seconds;i++)
for(j = 0; j < count; j++);
}

int main (void)
{
int game_loop = 3;
char c = ' ';  // fill console with blank space to clear screen
int successful_tries = 0;
//char newgame = 0;
int num = 0;
int input = 0;
int limit = 9;
int limit_2 = 1;

printf("This is a game to test your memory, with a random number of 1 digit that will be displayed a max of 3 successive times.\n");
clock_t t;
t = clock();
for ( ; game_loop > 0; --game_loop) // count down how many tries left until program ends
{
// code to compute random digits
srand(time(NULL));
num = limit_2 + rand() % limit;

printf("\n%d\n", num);
delay(1); 	// create 1 second program delay before clear screen with 'X's

// clear screen with x's
for (int ctr_1 = 1; ctr_1 < 7500; ctr_1++)
{
printf("%c", c);
}

printf("\n\n");

printf("\nYou have %d tr%s left.\n", game_loop, game_loop == 1 ? "y" : "ies");
printf("What sequence was displayed?: ");
scanf("%d", &input);

if (input == num) // corrected answer was inserted, increase sequence length. Go to beginning of progrem (program_begin--), sequence_length++);
{

int i = 0;

// where's score variable

while (i < 1)  // per one match (one correct match)
{
successful_tries += 1; // Successful tries for end of program
++i;
}

if (successful_tries == 3) // sequence was inserted 3 times in a row
{
limit += 191; // make sequence 3 digits
limit_2 += 49;  // limit_2 = limit_2 + 49;
}

if (successful_tries >= 3)
{
game_loop += 1;
}

/*
if (successful_tries >= 3) // if successful_tries is greater than or equal to 3
{
game_loop += 1; // increment game_loop + 1 infinitely
}
*/

}

else if (input != num) // only quits successful if game_loop is < 3
{
//while ((getchar()) != '\n');
break;
}
}

// The program will then calculate a score based on the number of successful tries and the time taken and invite the player to play again.
t = clock() - t;
double program_execution = ((double)t)/CLOCKS_PER_SEC; // in seconds
printf("You had %d successful tr%s. Program execution took %f seconds.\n", successful_tries, successful_tries == 1 ? "y" : "ies", program_execution);

return 0;
}``` Popular pages Recent additions #include, exercise, players, program, sequence 