How to use isdigit() for a pin while loop [closed] - c

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
This program accepts any four digit number as the pin , so i used a strlen() to find out whether the pin is has four characters, but I need to make sure that user enters four numbers, how do I use isdigit() before the loop and for the loop condition?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
char pin [4];
printf("Please enter your pin : \n") ;
scanf("%4s" , &pin) ;
system("cls") ;
while (strlen(pin) != 4) {
count = count + 1 ;
if(count < 3){
printf("Invalid Pin \n") ;
printf("Please enter your pin again \n") ;
scanf("%4s", &pin) ;
system("cls");
}
else if (count == 3){
printf("Sorry you can't continue , Please contact your bank for assistance !") ;
return 0 ;
}
}

There are so many issues with this code I may not have covered every one of them in this answer:
Where is your main function? You can't have code outside a function; that doesn't work. C code other than global variable declarations, assignments to constant values, typedefs, struct and enum definitions, must go in a function. In your case you probably want the main function to house the code starting at line 6.
When calling scanf with a string argument, don't take the address of the string - the array is a reference in and of itself.
Calling strlen(pin) before any value has been copied into pin is 100% undefined behavior. Since the memory is uninitialized the strlen function will keep looking for a null character and possibly go out of the array bounds.
C strings are null-terminated. When you declare a string intended to hold n characters, you need to declare the array with a size of n+1 to have room for the null character.

First to answer your question
I would write a helper function 'validatePin' which would check the pin length and validate that the pin is a numeric pin, you can extend this function to do any other validation you require. It might look something like the following
const int PIN_OK = 0;
const int PIN_INVALID_LEN = -1;
const int PIN_INVALID_CHARS = -2;
int validatePin(const char *pin)
{
// Valdiate PIN length
if (strlen(pin) != 4) return PIN_INVALID_LEN;
// Validate PIN is numeric
for (int i = 0; i < 4; ++i)
{
if (!isdigit(pin[i])) return PIN_INVALID_CHARS;
}
return PIN_OK;
}
Then you can adjust your while loop to look something like the following
while (validatePin(pin) != PIN_OK)
{
....
}
Other points regarding your code.
Your char buffer used for scanf does not account for the null terminator. You need to increase the buffer size.
The char array is already giving you the address of the buffer, there is no need to use & to take the address of the char array in scanf.
I have not run your code, so there might be other issues that I missed at first glance.

There are a number of ways to go about doing what you need to do. You can either check your input length, or just validate what it is you have read, your choice. One approach would be:
#include <stdio.h>
#include <ctype.h>
enum { TRIES = 3, NPIN };
int main (void) {
char pin[NPIN+1] = "";
size_t tries = 0, pinok = 0;
for (; tries < TRIES; tries++) { /* 3 tries */
printf ("Please enter your pin : ");
if (scanf (" %4[^\n]%*c", pin) == 1) { /* read pin */
pinok = 1;
size_t i;
for (i = 0; i < NPIN; i++) /* validate all digits */
if (!isdigit (pin[i]))
pinok = 0;
if (pinok) /* if pin good, break */
break;
}
}
if (!pinok) { /* if here and not OK, call bank */
fprintf (stderr, "Sorry you can't continue, Please contact "
"your bank for assistance.\n") ;
return 1;
}
printf ("\n correct pin : %s\n\n", pin); /* your pin */
return 0;
}
(note: to protect against an excessively long string entered at one time, you should empty stdin at the end of the outer for loop each iteration)
Example Use/Output
Failed case:
$ ./bin/pin
Please enter your pin : a555
Please enter your pin : 555a
Please enter your pin : 55a5
Sorry you can't continue , Please contact your bank for assistance.
Successful case:
$ ./bin/pin
Please enter your pin : 2345
correct pin : 2345
Look it over an let me know if you have any questions.

Related

"Segmentation fault 11" crashing in for loop

I'm super new to C programming, only taking it for a required course in uni and finally getting done with my final project this week.
Problem is every time I run this code I get an error message that says "segmentation fault: 11" and I'm not sure what that means.
The code is supposed to run two-player race. Each player has a pre-determined "speed modifier", aka a number from 0-9. A random number from 1-10 is generated; if the speed modifier + the random number doesn't exceed 10, then the speed modifier is added and the car moves that total amount of "spaces". The whole race track is 90 "spaces".
Every time I run this code it works somewhat fine (more on that later) for one or two iterations, then gives out that error message. I normally don't ask for homework help online but I'm honestly so confused. Any help at all would be super appreciated.
Here is the relevant code:
Race (main) function:
int race(struct car cars[4], int mode)
{
/* Define variables. */
int endgame, i, x, y, first=-1, second=-1, randnum, spaces[]={};
char input[100];
/* Declare pointer. */
int *spacesptr=spaces;
for (i=0; i<mode; i++)
{
/* Array spaces will keep track of how many spaces a car has moved. Start each car at 0. */
spaces[i]=0;
}
/* Clear screen before race. */
system("cls");
/* Print message to indicate race has started. */
printf("\n3...\n2...\n1...\nGO!\n\n");
/* Open do while loop to keep race running until it is over. */
do
{
/* Conditions for two player mode. */
if (mode==2)
{
/* Run the next block of code once for each player. */
for (i=0; i<mode; i++)
{
/* Generate random integer from 1-10 to determine how many spaces the car moves. */
x=10, y=1;
randnum=(getrandom(x, y));
spaces[i]=spaces[i]+randnum;
/* Call function speedmod to determine if speedmodifier should be added. */
speedmod(cars, spaces, randnum);
/* Rank players. */
if (spaces[i]>89)
{
if (first==-1)
{
first=i;
}
else if (second==-1)
{
second=i;
}
}
}
}
...
/* Call function displayrace to display the race. */
displayrace(cars, spaces, mode);
/* Call function endgame to determine if the race is still going. */
endgame=fendgame(mode, spaces);
if (endgame==0)
{
/* Ask for player input. */
printf("Enter any key to continue the race:\n");
scanf("%s", input);
/* Clear screen before loop restarts. */
system("cls");
}
} while (endgame==0);
}
Random number function:
int getrandom(int x, int y)
{
/* Define variable. */
int randnum;
/* Use time seed. */
srand(time(0));
/* Generate random numbers. */
randnum=(rand()+y) % (x+1);
return randnum;
}
Add speed modifier function:
void speedmod(struct car cars[4], int spaces [], int go)
{
/* Declare pointer. */
int *spacesptr=spaces;
/* If the number of spaces plus the speed modifier is less than or equal to ten... */
if (spaces[go]+cars[go].speedmod<=10)
{
/* ...add the speed modifier to the number of spaces moved. */
spaces[go]=spaces[go]+cars[go].speedmod;
}
}
Display race function:
void displayrace(struct car cars[4], int spaces[], int mode)
{
/* Define variables. */
int i, j;
/* Declare pointers. */
int *spacesptr=spaces;
struct car *carsptr=cars;
/* Open for loop. */
for (i=0; i<mode; i++)
{
/* Print racecar number. */
printf("#%d\t", cars[i].carnumber);
/* For every space the car has moved... */
for (j=0; j<spaces[i]; j++)
{
if (j<=90)
{
/* ...print one asterisk. */
printf("*");
}
}
/* New line. */
printf("\n");
}
}
End game function:
int fendgame(int mode, int spaces[])
{
/* Define variables. */
int racers=0, endgame=0, i;
/* Declare pointer. */
int *spacesptr=spaces;
/* Open for loop. */
for (i=0; i<mode; i++)
{
/* If any of the racers have not yet crossed the finish line (90 spaces)... */
if (spaces[i]<=90)
{
/* ...then add to the number of racers still in the game. */
racers++;
}
}
/* If all the racers have crossed the finish line... */
if (racers==0)
{
/* ...then end the game. */
endgame=1;
}
return endgame;
}
Now to be more specific on the issue...it's messing up somewhere on the "for" loop in the race function. For some reason it doesn't actually go through each iteration of "i", specifically in this line:
spaces[i]=spaces[i]+randnum;
I know this because I put in printf statements to display the value of spaces[i] before and after; the first iteration of i works fine...but the second iteration actually uses spaces[i-1] instead and adds the randnum to that value?
And then, like I said, it crashes after one or two times of this...:-(
I know it's a lot but I'm hoping someone more experienced than I could spot the error(s) in this code for me! Please help!
I believe the first user above was correct in saying that the error is because there is no initial size declared for the array, but the solution is incorrect. You would have to allocate its size dynamically using malloc.
Also, I'd shorten spaces[i]=spaces[i]+randnum to just spaces[i] += randnum.
regarding: Problem is every time I run this code I get an error message that says "segmentation fault: 11" and I'm not sure what that means.
This means your program is trying to access memory that the application does not own.
For instance, a 'wild' pointer or uninitialized pointer or writing past the end of an array.
Thanks for the help. After a ton of tinkering around with this code I finally found the issue.
I was passing randnum to the speedmod function as if it were an index of the array spaces. I changed the function to the following, where num is the random number generated and go is the index:
void speedmod(struct car cars[4], int spaces [], int num, int go)
{
/* Declare pointer. */
int *spacesptr=spaces;
/* If the number of spaces plus the speed modifier is less than or equal to ten... */
if (num+cars[go].speedmod<=10)
{
/* ...add the speed modifier to the number of spaces moved. */
spaces[go]+=cars[go].speedmod;
}
}
Works perfectly now. Thanks for the help again.
you declare spaces[]={}, so it allocates a ptr that points to nothing. then you start writing all over it, which destroys probably your stack, your other variables, and whatever else is there -> undefined behavior.
you need to provide the memory to write to before you use it, for example spaces[1000]={}, ot however much you need.

Check only last 3 digits of sensor output

I have a library from WiringPi for DHT11 sensor and I need to modify condition which checks if the value read from sensor is good.
Sometimes the library reads bad values which are 255.255,255.255 or 55,255.255 etc.
sample output
There is the condition in the library:
if(counter==255)
break;
But it doesn't work if the value is e.g. 55,255.255
How can I modify this condition the check last 3 digits of output?
If the output is wrong, there are always "255" at the end of value.
I tried to add conditions like
if(counter==255)
break;
else if(counter==255.255)
break;
But it doesn't solve all possible situations and I realy don't know anything about C/C++
Here is the whole library:
#include <wiringPi.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#define MAX_TIME 85
#define DHT11PIN 7
#define ATTEMPTS 5
int dht11_val[5]={0,0,0,0,0};
int dht11_read_val()
{
uint8_t lststate=HIGH;
uint8_t counter=0;
uint8_t j=0,i;
for(i=0;i<5;i++)
dht11_val[i]=0;
pinMode(DHT11PIN,OUTPUT);
digitalWrite(DHT11PIN,LOW);
delay(18);
digitalWrite(DHT11PIN,HIGH);
delayMicroseconds(40);
pinMode(DHT11PIN,INPUT);
for(i=0;i<MAX_TIME;i++)
{
counter=0;
while(digitalRead(DHT11PIN)==lststate){
counter++;
delayMicroseconds(1);
if(counter==255)
break;
}
lststate=digitalRead(DHT11PIN);
if(counter==255)
break;
// top 3 transistions are ignored
if((i>=4)&&(i%2==0)){
dht11_val[j/8]<<=1;
if(counter>16)
dht11_val[j/8]|=1;
j++;
}
}
// verify checksum and print the verified data
if((j>=40)&&(dht11_val[4]==((dht11_val[0]+dht11_val[1]+dht11_val[2]+dht11_val[3])& 0xFF)))
{
printf("%d.%d,%d.%d\n",dht11_val[0],dht11_val[1],dht11_val[2],dht11_val[3]);
return 1;
}
else
return 0;
}
int main(void)
{
int attempts=ATTEMPTS;
if(wiringPiSetup()==-1)
exit(1);
while(attempts)
{
int success = dht11_read_val();
if (success) {
break;
}
attempts--;
delay(500);
}
return 0;
}
No single variable in your code can hold "255.255", that would require a string or a float. You are obviously referring to the output of
printf("%d.%d,%d.%d\n",dht11_val[0],dht11_val[1],dht11_val[2],dht11_val[3]);.
This printf can never produce a three-value output like 55,255.255.
I assume that your output would be 55.255,255.255.
This in turn means that in case of error you will find the "last three digits" in dht11_val[3].
If my assumption is not correct please provide much more detail on the error circumstances.
On the other hand, I suspect that looking for that value is not the solution for your problem either. The function is more complicated. The value of 255 seems the result of an endless loop which is detected by breaking early at counter = 255. So I am pretty sure that checking "the last three digits" is a LESS precise check than what is already implemented.

Galton Box/Bean Machine-C

I want to code a simple bean machine program. The program will accept user input for the number of balls and the number of slots, and will calculate the path of each ball. The number of balls in each slot will be printed as a histogram as well.
I tried my best to keep the code short and sweet, yet the best I have managed is 112 lines long. When I ran my code, I received no errors. However, the output seems to have run into some sort of an infinity loop (The '#' symbol which was used to represent numbers in the histogram keeps on printing forever for some reason unknown to me).
Apparently, there is something wrong with my logic somewhere... or a silly little mistake in syntax(but it would have shown up as error, wouldn't it?)... In a nutshell, I cannot figure out exactly what is the problem. (I attempted to walk through the whole code process from start to finish, but my mind kept getting tangled up somewhere in the middle of the code, nowhere near the end of the code either).
Where exactly does my logic go wrong?(Or have I taken the wrong approach to the whole problem?) I do not wish to know the correct code, so that I am able to learn during the whole process of re-editing my code.
Any help (hopefully no model-code answers though), even as a single comment, is tremendously appreciated! :)
This is my code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <conio.h>
#include <stdbool.h>
#include <time.h>
//Pls excuse my extensive use of libraries even though I don't really use them
int intchecker(float x)
{
if (floor(x)==x && ceilf(x)==x)
{
return 0;
}
else {
return 1;
}
}
int main(){
char line[] = " +----+----+----+----+----+----+----+----+----+----+---+";
char numbers[] = " 0 5 10 15 20 25 30 35 40 45 50";
float balls,slots;
int slotarry[9],tlevel,ballnum,column,lcounter=0,slotsduplicate=1,y;//tlevel-number of levels in the triangle
srand(time(NULL));
int r;
printf("==========================================================\nGalton Box Simulation Machine\n==========================================================\n");
printf("Enter the number of balls [5-100]: ");
scanf("%f",&balls);
while (balls>100 || balls<5) {
printf("\nInput is not within the range. Please try again.");
printf("\nEnter the number of balls [5-100]: ");
scanf("%f",&balls);
}
while (intchecker(balls)==1) {
printf("\nInput is not an integer. Please try again.");
printf("\nEnter the number of balls [5-100]: ");
scanf("%f",&balls);
}
printf("Enter the number of slots [2-10] : ");
scanf("%f",&slots);
while (slots>10 || slots<2) {
printf("\nInput is not within the range. Please try again.");
printf("\nEnter the number of slots [2-10] : ");
scanf("%f",&slots);
}
while (intchecker(slots)==1) {
printf("\nHow can there be a fraction of a slot? Please re-enter slot number.");
printf("\nEnter the number of slots [2-10] : ");
scanf("%f",&slots);
}
tlevel=slots-1;
for(ballnum=1,column=0;balls>0;balls--,ballnum++,column++){
if (column%5==0){
printf("\n");
}
if (ballnum<10){
printf("[0%d]",ballnum);
}
else{
printf("[%d]",ballnum);
}
for(;tlevel>0;tlevel--){
r = rand() % 2;
if (r==0){
printf("R");
}
else {
printf("L");
lcounter++;
}
}
slotarry[lcounter]++;
tlevel=slots-1;
lcounter=0;
printf(" ");
}
printf("\n\n%s",numbers);
printf("%s",line);
char line2[] = "\n +----+----+----+----+----+----+----+----+----+----+---+";
for(;slotsduplicate<=slots;slotsduplicate++){
if (slotsduplicate<10){
printf("0%d|",slotsduplicate);
}
else{
printf("%d|",slotsduplicate);
}
y=slotarry[slotsduplicate];
if (y==0){
printf(" 0");
}
else{
for (;y>0;y--){
printf("#");
}
printf(" %d",slotarry[slotsduplicate]);
}
printf("%s",line2);
}
return 0;
}
Note:This is not completely error-free. This is just my first draft. I just wish to find out why there is an infinite loop.
Here's how I found the problem. First of all, I think it is a bit of a code smell to have a for loop without anything in the initial assignment section. Couple that with the fact that it seems to print # forever, and it looks like y has a garbage value at the beginning of the loop to print the #s.
So I ran your code in the debugger and paused it when it started printing loads of hashes. I checked the value of y and sure enough it was some unfeasibly high number.
Then I checked where y comes from and found you get it from slotarray. I printed it in the debugger and found that all the values in it were unfeasibly high or massively negative numbers. Obviously, slotarray wasn't being initialised correctly, so I looked for where it was initialised and bingo!
Stack variables (of which slotarray is one) must be explicitly initialised in C. I fixed your code with a call to memset.
The whole debugging process I have just outlined took something less than a minute.
ETA As #EOF points out, there is another bug in that slotarray is defined to contain nine slots (indexed 0 - 8) but you allow people to enter 10 slots. This is a buffer overflow bug.

Creating a basic stack overflow using IDA

This program is running with root privileges on my machine and I need to perform a Stack overflow attack on the following code and get root privileges:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <openssl/sha.h>
void sha256(char *string, char outputBuffer[65])
{
unsigned char hash[SHA256_DIGEST_LENGTH];
int i = 0;
SHA256_CTX sha256;
SHA256_Init(&sha256);
SHA256_Update(&sha256, string, strlen(string));
SHA256_Final(hash, &sha256);
for(i = 0; i < SHA256_DIGEST_LENGTH; i++)
{
sprintf(outputBuffer + (i * 2), "%02x", hash[i]);
}
outputBuffer[64] = 0;
}
int password_check(char *userpass)
{
char text[20] = "thisisasalt";
unsigned int password_match = 0;
char output[65] = { 0, };
// >>> hashlib.sha256("Hello, world!").hexdigest()
char pass[] = "315f5bdb76d078c43b8ac0064e4a0164612b1fce77c869345bfc94c75894edd3";
text[0] = 'a';
text[1] = 't';
text[2] = 'j';
text[3] = '5';
text[4] = '3';
text[5] = 'k';
text[6] = '$';
text[7] = 'g';
text[8] = 'f';
text[9] = '[';
text[10] = ']';
text[11] = '\0';
strcat(text, userpass);
sha256(text, output);
if (strcmp(output, pass) == 0)
{
password_match = 1;
}
return (password_match == 1);
}
int main(int argc, char **argv)
{
if (argc < 3)
{
printf("Usage: %s <pass> <command>\n", argv[0]);
exit(1);
}
if (strlen((const char *) argv[1]) > 10)
{
printf("Error: pasword too long\n");
exit(1);
}
if (password_check(argv[1]))
{
printf("Running command as root: %s\n", argv[2]);
setuid(0);
setgid(0);
system(argv[2]);
}
else
{
printf("Authentication failed! This activity will be logged!\n");
}
return 0;
}
So I try to analyse the program with IDA and I see the text segment going from the lower addresses to the higher addresses, higher than that I see the data and then the bss and finally external commands.
Now as far as I know the stack should be just above that, but I'm not certain how to view it, how exactly am I supposed to view the stack in order to know what I'm writing on? (Do I even need it or am I completely clueless?)
Second question is considering the length of the input, how do i get around this check in the code:
if (strlen((const char *) argv[1]) > 10)
{
printf("Error: pasword too long\n");
exit(1);
}
Can I somehow give the string to the program by reference? If so how do I do it? (Again, hoping I'm not completely clueless)
Now as far as I know the stack should be just above that, but I'm not certain how to view it, how exactly am I supposed to view the stack in order to know what I'm writing on? (Do I even need it or am I completely clueless?)
The stack location varies all the time - you need to look at the value of the ESP/RSP register, its value is the current address of the top of the stack. Typically, variable addressing will be based on EBP rather then ESP, but they both will point to the same general area of memory.
During analysis, IDA sets up a stack frame for each function, which acts much like a struct - you can define variables with types and names in it. This frame is summarized at the top of the function:
Double-clicking it or any local variable in the function body will open a more detailed window. That's as good as you can get without actually running your program in a debugger.
You can see that text is right next to password_match, and judging from the addresses, there are 0x14 bytes allocated for text, as one would expect. However, this is not guaranteed and the compiler can freely shuffle the variables around, pad them or optimize them into registers.
Second question is considering the length of the input, how do i get around this check in the code:
if (strlen((const char *) argv[1]) > 10)
{
printf("Error: pasword too long\n");
exit(1);
}
You don't need to get around this check, it's already broken enough. There's an off-by-one error.
Stop reading here if you want to figure out the overflow yourself.
The valid range of indices for text spans from text[0] through text[19]. In the code, user input is written to the memory area starting at text[11]. The maximum input length allowed by the strlen check is 10 symbols + the NULL terminator. Unfortunately, that means text[19] contains the 9th user-entered symbol, and the 10th symbol + the terminator overflow into adjacent memory space. Under certain circumstances, that allows you to overwrite the least significant byte of password_match with an arbitrary value, and the second least significant byte with a 0. Your function accepts the password if password_match equals 1, which means the 10th character in your password needs to be '\x01' (note that this is not the same character as '1').
Here are two screenshots from IDA running as a debugger. text is highlighted in yellow, password_match is in green.
The password I entered was 123456789\x01.
Stack before user entered password is strcat'd into text.
Stack after strcat. Notice that password_match changed.

Return not ending method in c

edit - i figured out the arithmetic error but I still have the return error
For some reason my program is giving me two errors. First error is that the "return" at the end of each of my methods() are not ending the method and bring me back to main. My second question is at line 23 where pfNum = mainSize/pageSize; is giving me a "SIGFPE, arithmetic exception" not sure why both of these are occuring can anyone help me out?
Thanks
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
/* Define page table as dynamic structure containing virtual page and page frame
and initialize variable as pointer to structure */
struct table{
int vp;
int pf;
}*pageTable = NULL;
/* Declare global var's */
int mainSize,pageSize,policy,pfNum;
/**********************************************************************/
void option1(){
/* Declare local var's */
int k;
/* Prompt for main memory size, page size, and replacement policy */
printf("Enter main memory size(words): ");
scanf("%d",&mainSize);
printf("Enter page size(words/page): ");
scanf("%d",&pageSize);
printf("Enter replacement policy(0=LRU, 1=FIFO): ");
scanf("%d",&policy);
pfNum = mainSize/pageSize;
/* Allocate and initialize page table based on number of entries */
pageTable = malloc(pfNum *sizeof(pageTable));
for(k=0;k<pfNum;k++){
pageTable[k].vp=-1;
pageTable[k].pf=k;
}
return;
}
/**********************************************************************/
void option2(){
/* Declare local var's */
int va,page,offset,i=0,temp;
/* Prompt for virtual address */
printf("Enter virtual memory address to access: ");
scanf("%d",&va);
/* Translate virtual mem addr to virtual page and offset*/
page = va/pageSize;
offset = va%pageSize;
/* Check for end of table, unallocated entry, or matched entry in table
and update table appropriately; while none of three cases, keep looping */
while(i<pfNum && pageTable[i].vp!=1 && pageTable[i].vp!=page)
i++;
if(i<=pfNum){
int j;
temp = pageTable[0].pf;
for(j=1;j<pfNum;j++)
pageTable[j-1]=pageTable[j];
pageTable[j].vp=page;
pageTable[j].pf=temp;
printf("Page Fault!");
}
else if(pageTable[i].vp==-1){
pageTable[i].vp = page;
printf("Page fault!");
}
else if(pageTable[i].vp==page){
temp = pageTable[i].pf;
int l,address;
for(l=i+1;l<pfNum-1;l++)
pageTable[l-1]=pageTable[l];
pageTable[l].vp = page;
pageTable[l].pf = temp;
address = (temp*pageSize)+offset;
printf("Virtual address %d maps to physical address %d",va,address);
}
return;
}
/**********************************************************************/
void option3(){
/* Declare local var's */
int u;
for(u=0;u<pfNum;u++ && pageTable[u].vp!=-1)
printf("VP %d --> PF %d",pageTable[u].vp,pageTable[u].pf);
/* Print out each valid virtual page and page frame pair in table */
return;
}
/**********************************************************************/
int main(){
/* Declare local var's */
int choice;
/* Until user quits, print menu of options, prompt for user input, and select appropriate option */
printf("/n");
printf("Virtual memory to Main memory mapping:\n");
printf("--------------------------------------\n");
printf("1) Set parameters\n");
printf("2) Map virtual address\n");
printf("3) Print page table\n");
printf("4) Quit\n");
printf("\n");
printf("Enter Selection: ");
scanf("%d",&choice);
printf("\n");
while(choice!=4){
if(choice==1)
option1();
else if(choice==2){
option2();
}
else if(choice==3)
option3();
}
printf("Goodbye. Have a nice day.");
return 1;
}
The "SIGFPE, arithmetic exception" exception is most likely caused by division by zero.
One problem is that once you've made your initial choice, nothing changes choice again, so the program goes around the loop, executing your initial choice (possibly doing nothing at all, since you don't validate for zero, negative choices, or values greater than four). This might give the appearance that your functions "don't return" but actually they do return; they just get called again almost immediately.
You probably need to prompt for a new choice each time around the loop, which suggests a function to prompt and return the choice which you call from a while loop.
You have at least one "/n" where you probably intended "\n". Your farewell message is missing its newline; so are a number of other messages (such as the "Page Fault!" messages). You don't check that your input functions were successful. You don't check that the memory allocation was successful.
Your SIGFPE probably comes from division by zero; print the values you're processing before you execute the division.

Resources