why this program gives a "segmentation fault" when run on my linux? - c

Write a program for a match stick game being played between the computer and a user.Your program should ensure that the computer should ensure that the computer always wins.Rules for the game are as follows:
-There are 21 matchsticks.
-The computer asks the player to pick 1,2,3 or 4 matchsticks.
-After the person picks,the computer does its picking.
-Whoever is forced to pick up the last matchstick loses the game.
#include<stdio.h>
main()
{
int n,rem;
printf("Initially 21 mathces\n");
rem=21;
for(;1;)
{
if(rem==1){
printf("Com wins\n");
break;
}
else if(rem==0){
printf("Player wins\n");
break;
}
else{
printf("Player's turn.Enter number:");
scanf("%d",n);
rem=rem-n;
}
printf("remaining sticks=%d",n);
if(rem==1){
printf("Player wins");
break;
}
else if(rem==0){
printf("Com wins");
break;
}
else{
if(rem>6){
if((rem-6)<=4){
n=rem-6;
}
if((rem-6)>4){
n=4;
}
}
if(rem==6) n=1;
if(rem<6){
n=rem-1;
}
printf("Com chooses: %d",n);
}
printf("Remaining sticks=%d",rem);
}
}

scanf function expects address of the variable, you have passed the (value of) variable itself.
scanf("%d",n);
Use this way:
scanf("%d",&n); // '&' is 'address of' operator and evaluates to address of the variable
You are getting Seg Fault because scanf treats n as address of some variable, however n contains some garbage value, and may be that garbage value is some inaccessible/disallowed address in memory, therefore you get Seg Fault.
It is an undefined behavior, may be tomorrow you restart your system and do not get Seg Fault, but anyways your code will not work the way you want it to.

Related

Code fails to give expected result, stacking loops

I'm a student and I'm currently learning C without much experience on programming, I've been trying to create a program that receives a "password" from the user and then proceeds to check if the password has at least one letter,number and special character. I wrote some code but it doesn't give the expected results while I struggle to find what's wrong with it.
If I input a "just numbers" password or "just special characters" it does fine by returning "You missed a letter"
If I input a "just characters" password it doesn't return anything, same for a normal password that contains all 3
That's the code:
int main()
{
char a[20];
int b = 0 ,c = 0,d=0;
printf("Please type your password and make sure it contains a letter a number and a special character:");
scanf("%s",a);
while(b<=20){
if(isalpha(a[b])){
break;
while(c<=20){
if(isdigit(a[c])){
break;
while(d<=20){
if(isalpha(a[d]) || isdigit(a[d])){
d++; continue;
}else{
printf("Congratulations your Password has been saved\n");
}
} printf("You missed a special character\n");
}else{c++; continue;}
}
printf("You missed a number\n");
}else{b++; continue;}
}
(b>20) ? printf("You missed a letter\n") : printf("");
return 0;
}

C - segmentation fault when comparing integers

here is a part of my code. When I run my code, it's requesting an input from user and then matching it with another integer which recorded in my structure. When user input is matching, it is working correct. But when user enters a wrong input, it gives a segmentation fault. In where, I should make changes on my code?
long int userInput,endCheck; // Input from user
int flag=0; // check for match
int status;
int c; // controlling ctrl+D
int position= 999; // position of where the user input and data matched
LABEL:
printf("\n\t---------------------------------------\n");
printf("\n\nPlease enter the student ID which you want to find(3-times CTRL+D for finish):\n");
scanf("%d",&userInput);
if( (c=getchar()) == EOF){
exit(0);
}
for(i=0;i<lines,flag==0;i++){
if(index[i].id == userInput){
position=i;
flag=1;
}else{
position=999;
}
}
if(flag==0){
printf("id not found");
}
studentInfo info; // for storing the information which we will take between determined offsets
if(position!= 999){
if ( (pos = lseek(mainFile,index[position].offset , SEEK_SET)) == -1)/*going to determined offset and setting it as starting offset*/
{ perror("classlist"); return 4; }
while ( (ret= read(mainFile,&info, sizeof(info))) > 0 ){
printf("\n\nStudent ID: %d, Student Name: %s\n\n",info.id,info.name);
break;// to not take another students' informations.
}
}
flag=0;
goto LABEL;
printf("Program is terminated");
The right way to do that loop with the unwanted comma is like this. When you find the right index[i].id you can exit the loop early by using break.
for(i=0;i<lines;i++){
if(index[i].id == userInput){
position=i;
flag=1;
break;
}
}
You don't need the else branch as position is set to 999 from the outset of the code. But really you shouldn't use position in this fashion. What if you have more than 999 records? You're already using flag to identify if you've set position to a valid value. You should replace any instance of if(position!= 999) with if(flag).
Or since position is a signed int, you could use a negative value and ditch the flag.
The reason can be the fact that you are reaching an index that doesn't exist in the end of cycle, in the moment of the "if" statement with iterator "i".
Or in the last if, where you access a "position" index of the array. Check those limits.
Also, try GDB, is useful for solving this kind of problems.

C Program not going inside loop for Guess the number

I have written the following code for the computer to guess what my number is, I have used switch case statement here which is inside a do while loop.
When I tried to run the program, the program doesnt go inside my loop, and I dont know how to fix it, can anyone help me out please?
#include<stdio.h>
void main()
{
printf("\n Grenze 1 - Obergrenze. ");
int min=1;
int max;
printf("\n Was ist Obergrenze? ");
scanf("%i",max);
int try=max;
int correct;
int input,i=0;
do{
correct=max/2;
printf("Low(1) High(2) oder Correct(3)? \n >");
start:
scanf("%i",input);
i++;
switch (input)
{
case(1):
{
min=min;
max=max/2;
} break;
case(2):
{
min=max/2;
max=max;
}break;
case(3):
{
goto gotcha;
}break;
default:
{
printf("\n >");
goto start;
}break;
}
}
while(i<try);
gotcha:
printf("\n Wieder gewonnen!!! Versuche - %i",i);
}
You are invoking undefined behavior by passing what is not a pointer and using value of uninitialized variable having automatic storage duration, which is indeterminate, inscanf("%i",max);.
The same problem is in scanf("%i",input);.
Use unary & operator to pass the address to read data into likescanf("%i",&max); and scanf("%i",&input);.
Also note that you should use standard int main(void) in hosted environment instead of void main(), which is illegal in C89 and implementation-defined in C99 or later, unless you have some special reason to use non-standard signature.

Integer variable changing value in C when it's not supposed to

I have no idea what's going on here. A project I am working on is the 2048 game. I am programming it in c. The thing is, I initially declared the score as 0 and have not implemented the scoring system yet but randomly it changes to 4? (I have it printed out)
Here's part of my code:
for(;;){
printf("Score: %d",user_score);
rand_i=rand()%(board_size+1);
rand_j=rand()%(board_size+1);
while(M[rand_i][rand_j]!=0){
rand_i=rand()%(board_size+1);
rand_j=rand()%(board_size+1);
}
rand_num= rand()%2*2+2;
M[rand_i][rand_j]=(rand_num);
for(i=0;i<board_size;i++){
printf("\n");
for(j=0;j<board_size;j++){
if (M[i][j]==0){
printf("[ ]");
}
else printf("[%4d]",M[i][j]);
}
}
printf("\n(w=up, a=left, s=down, d=right, q=quit) > ");
scanf("%c%c",&user_input);
//system("clear");
switch(user_input){
case 'w':
for(j=0;j<board_size;j++){
for(i=0;i<board_size;i++){
if(M[i][j]!=0 && i!=0){
for(k=i;k>0;k--){
if(M[k-1][j]==0){
M[k-1][j]=M[k][j];
M[k][j]=0;
I think you are writing beyond array M.
rand_i=rand()%(board_size+1);
rand_j=rand()%(board_size+1);
If M is declared as int M[board_size][board_size], than rand_i and rand_j could be one too large.
Hope this helps.

program running through my if else after function call

I have a class assignment in C to make a simple calculator that performs three calculations. I haven't completed all of the functions yet but I am having a problem with my calcMenu function. When the function is called the program runs through all of the if else statements and unknown to me, performs only the else statement which is error checking. Than the function is run again which is intended but this time it does not run through all of the if else statements and allows the user to make a choice. I know I have done something really stupid but have been racking my brain for the last hour. If anyone has any pitty for me, than please point me in the right direction. I know all the system calls will Irk some but this is a basic class and our instructor has told us to use them.
Thanks in advance,
Mike
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#define pause system ("pause")
#define cls system ("cls")
//Prototype calculate functions here
void evenOrOdd(int userNumber);
void squareNum(int userNumber);
void cubeNum(int userNumber);
void calcMenu(int userNumber);
void main() {
//Declare local variables here
int userNumber = 0;
printf("\t\t\tThe amazing three function caluculator\n\n\n");
printf("Please enter a whole number that you would like to calculate\n");
scanf("%d", &userNumber);
calcMenu(userNumber);
}
void calcMenu(int userNumber)
{
char calculateOption;
printf("\nWhat calculation would you like to perform with your number?\n\n");
printf("Press A.) to check if your number is even or odd.\n\n");
printf("Press B.) to calculate the square of your number.\n\n");
printf("Press C.) to calculate the cube of your number.\n\n");
printf("press D.) to exit the program.\n");
scanf("%c", &calculateOption);
calculateOption = toupper (calculateOption);
if (calculateOption == 'A')
{
evenOrOdd(userNumber);
}
else if (calculateOption == 'B')
{
squareNum(userNumber);
}
else if (calculateOption == 'C')
{
cubeNum(userNumber);
}
else if (calculateOption == 'D')
{
system("cls");
printf("Thank You for using my amazing calculator.\n\n");
system ("pause");
system ("exit");
}
else
{
printf("Please enter a valid choice");
calcMenu(userNumber);
}
}
void evenOrOdd(int userNumber) {
userNumber = userNumber %2;
if (userNumber == 0)
{
printf("Your number is even. \n");
}
else
{
printf("Your number is odd. \n");
}
}
void squareNum(int userNumber) {
}
void cubeNum(int userNumber){
}
When you read input with scanf you have to press the Enter key to make the program continue. Your scanf call reads the single character from the input, but leaves the Enter key still in the input buffer, to be read next time you call scanf.
There is a very simple trick to solve that: Place a space in the scanf format string before or after the "%c". This will make scanf skip whitespace.
scanf("%c ", &calculateOption);
If you stepped through the code with a debugger you would have easily seen that calculateOption would have been the newline character.
First of all, You can condense all those printf statements into one function to save the extra calls.
Next, you should probably indent your functions, I can't tell where one begins and another ends at a glance.
Third, don't use system("pause"), use getchar().
Fourth, this is optional, you might want to turn those if statements into a switch statement.
Now, on to your question. First of all, instead of using scanf("%c", &calculateOption), just use getchar() here too. In this case, I would write calcMenu() as this:
int calcMenu(int userNumber){
printf("\nWhat calculation would you like to perform with your number?\n\n\
Press A.) to check if your number is even or odd.\n\n\
Press B.) to calculate the square of your number.\n\n\
Press C.) to calculate the cube of your number.\n\n\
Press D.) to exit the program.\n");
switch(toupper(getchar())){
case 'A':
evenOrOdd(userNumber);
break;
case 'B':
squareNum(userNumber);
break;
case 'C':
cubeNum(userNumber);
break;
case 'D':
system("cls"); //this is bad, really.
printf("Thank You for using my amazing calculator.\n\n");
getchar();
return 0;
default:
printf("Please enter a valid choice: ");
calcMenu(userNumber);
break;
}
}
Also, main should always return a value. void main is bad practice.
Disclaimer: The code isn't tested, you shouldn't copy/paste it anyways. I also don't know if you're being forced to use some things or not...

Resources