Program keeps running even after the error appeared - c

I have a program that retrieves some numbers from a file into an array. The last problem that I have is that my program keeps running even though it cannot open the file, instead of ending it. Even when it says program is over, the menu from main appears again but doesn't show any data
int main (void)
{
int choice, max, min;
float avg;
int test[MAX_NUMBER_OF_STUDENTS];
int file_opened;
int number_of_students;
file_opened = get_test_scores(test, &number_of_students);
if (file_opened == 0)
{
do
{
choice = menu();
switch (choice)
{
case 0: printf("\nProgram is over.\n");
break;
case 1: test_avg(&avg, test, number_of_students);
printf("\nAverage score on test = %5.2f\n", avg);
break;
case 2: test_max_min(number_of_students, &max, &min, test);
printf("\nMaximum score = %3d\n"
"Minimum score = %3d\n", max, min);
break;
case 3: print_test(test,number_of_students);
break;
default:
printf("This should never happen!");
}
} while (choice != 0);
}
return 0;
}
int get_test_scores(int test[], int* size)
{
FILE* sp_input; // Pointer to the input stream (from a file)
int i;
sp_input = fopen("a20.dat", "r");
if (sp_input == NULL)
printf("\nUnable to open the file a20.dat\n");
else
{
while( fscanf(sp_input, "%d", &test[i])!=EOF)
{
i=i+1;
++*size;
}
fclose(sp_input); // Close the stream
}
return 1;
}

Yes, it keeps running...
if (file_opened == 0)
{
do
{
means that if the file has not been opened, to do the loop. You want:
if (file_opened != 0)
See also comments about other bugs.

Related

My static stack code is not running properly

#include <stdio.h>
#include <stdlib.h>
#define N 5
int stack[N];
int top = -1;
void push()
{
int x;
printf("Enter data");
scanf("%d", &x);
if (top == N - 1)
{
printf("Overflow");
}
else
{
top++;
stack[top] = x;
}
}
void pop()
{
int item;
if (top == -1)
{
printf("Underlfow");
}
else
{
item = stack[top];
top--;
printf("%d", item);
}
}
void peek()
{
if (top == -1)
{
printf("Underflow");
}
else
{
printf("%d", stack[top]);
}
}
void display()
{
int i;
for (i = top; i >= 0; i--)
{
printf("%d\n", stack[top]);
}
}
int main()
{
int ch;
do
{
printf("\n1.push\n2.pop\n3.peek\n4.display");
scanf("%d", &ch);
switch (ch)
{
case 1:
push();
break;
case 2:
pop();
break;
case 3:
peek();
break;
case 4:
display();
break;
case 5:
exit(0);
break;
default:
printf("invalid key pressed");
break;
}
} while (ch != 0);
return 0;
}
So it is the code which i wrote following a tutorial on youtube
In push function if i excced the array size which is 5 it will still take values instead of printing overflow and when i try to display it, it will display all values same
before i was geting a error at getch(); while using void main() so i change it to int main() and used return 0; it is still not working.
So it is the code which i wrote following a tutorial on youtube In push function if i excced the array size which is 5 it will still take values instead of printing overflow and when i try to display it, it will display all values same
Your logic is to always allow you to enter values. But they are not inserted in the stack (and instead "Overflow" is printed). This is because you ask for the value before checking if the stack is full. Just make the test before, and put the scan inside the else part of the if statement.
void push()
{
int x;
if (top == N - 1) {
/* put \n chars at end of lines in output statements
* like this ---vv */
printf("Overflow\n");
} else {
printf("Enter data ");
fflush(stdout);
scanf("%d", &x);
top++;
stack[top] = x;
}
}
The problem of printing always the top of the stack is basically that you print stack[top], instead of stack[i], in the display() function loop. You should use this code instead.
void display()
{
int i;
for (i = top; i >= 0; i--)
{
/* use i here --------------v */
printf("%d: %d\n", i, stack[i]);
}
}
This is not an error, but will save you trouble in the future. Get used to put the \n char at the end of the printing format, instead of at the beginning, if you are going to print a complete line. I understand that you want to avoid it when prompting the user, so you avoid it. But the stdio library uses buffering, so it doesn't print things when you ask it for, so it delays the printing of strings (on an interactive session) until you do printf a '\n' char (if the output device is a terminal), or before reading from stdin (also, if the input device is a terminal). This can make a mess if you print your strings without the trailing '\n'. And more, if you redirect your output, this means using a pipe (so, it is not a terminal). Then, no output is done until the buffer fills completely (meaning over 10kb of data, usually 16kb on modern unix/linux systems) You will see your program doing things while no output has been output, and you won't know why.
You don't use getch() in your code, so i think you have posted a different version of the code you are talking about.
My code, after edition, leads to:
#include <stdio.h>
#include <stdlib.h>
#define N 5
int stack[N];
int top = -1;
void push()
{
if (top == N - 1) {
/* no overflow yet, not if we check beforehand :) */
printf("Stack full, cannot push()\n");
} else {
int x;
printf("Enter data ");
fflush(stdout); /* to flush the output (no \n at end) */
scanf("%d", &x);
top++;
stack[top] = x;
printf("Push: %d to position %d\n", x, top);
}
}
void pop()
{
if (top == -1) {
/* the appropiate message is stack empty, no underflow has
* occured yet. We are preventing it */
printf("Stack empty, cannot pop()\n");
} else {
int item = stack[top];
printf("Pop: %d from pos %d\n", item, top);
top--;
}
}
void peek()
{
if (top == -1) {
/* no underflow yet, we are preventing it */
printf("Stack empty, cannot peek()\n");
} else {
printf("Peek: %d on pos %d\n", stack[top], top);
}
}
void display()
{
int i;
printf("Stack contents:\n");
for (i = top; i >= 0; i--) {
printf("> %d: %d\n", i, stack[i]);
}
}
int main()
{
int ch = 5; /* so we exit if no valid input is made in scanf() */
do {
printf("1.push\n"
"2.pop\n"
"3.peek\n"
"4.display\n"
"5.exit\n");
scanf("%d", &ch);
switch (ch) {
case 1:
push();
break;
case 2:
pop();
break;
case 3:
peek();
break;
case 4:
display();
break;
case 5:
break;
default:
printf("Input invalid option\n");
break;
}
} while (ch != 5); /* option 5 is to exit */
return 0;
}

Saving a char value with fwrite returns incorrect data when loaded

I am using the frwite feature to save previous math equation result data and the code works when using integers but if I use char values (which I am trying to implement in order to make a certain future feature possible), I get weird values back. For example when the result 50 was saved, when the data was loaded I got the following:
2
2
The following is the code I wrote in question:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <cbm.h>
int integer1;
int integer2;
int integer3;
int option;
char save;
char c;
FILE *fp; //?????
void startup() {
textcolor (COLOR_WHITE);
bordercolor (COLOR_BLACK);
bgcolor (COLOR_BLACK);
clrscr ();
}
void get2nums() {
printf("FIRST NUMBER?\n");
scanf("%d", &integer1);
printf("SECOND NUMBER?\n");
scanf("%d", &integer2);
}
void addition() {
get2nums();
save = integer1 + integer2; //save into the save variable which will provide input to the save file function
printf("%d", save);
printf("\n");
}
void subtraction() {
get2nums();
save = integer1 - integer2; //save into the save variable which will provide input to the save file function
printf("%d", save);
printf("\n");
}
void multiplication() {
get2nums();
save = integer1 * integer2; //save into the save variable which will provide input to the save file function
printf("%d", save);
printf("\n");
}
void division() {
get2nums();
if(integer2 == 0)
printf("Div by 0 undefined\n");
else
save = integer1 / integer2; //save into the save variable which will provide input to the save file function
printf("%d with %d remainder", integer1 / integer2, integer1 % integer2);
printf("\n");
}
static void savedata(void) {
char data_out = save; //Data that goes into the file
//Saving
_filetype = 's'; //Does this set the file as a .SEQ?
if ((fp = fopen ("CALCDATA", "w")) == 0) {
printf("ERROR COULD NOT OPEN FILE\n\r"); //Error handler
printf("CHECK DISK DRIVE\n");
exit(1);
}
fwrite (&data_out, sizeof(data_out), 1, fp);
fclose (fp);
}
static void loaddata(void) {
_filetype = 's';
if ((fp = fopen ("CALCDATA", "r")) == 0) {
printf("ERROR COULD NOT OPEN FILE\n\r");
printf("CHECK DISK DRIVE\n");
exit(1);
}
while (1) {
c = fgetc (fp);
if (feof (fp)) {
break;
}
printf("\n");
printf ("%c\n", c);
}
fclose (fp);
}
void debug() {
printf("%d", save);
}
int main() {
startup();
for( ;; ) { // uncomment this line and below for infinite looping
printf("\n");
printf("ADVANCED CALCULATOR VERSION 0.9\n");
//printf("CODED BY REDACTED\n");
//printf("BUILD DATE: 12/12/2022\n");
//delay(5000);
//clrscr ();
printf("CALCULATOR OPTIONS ARE:\n");
printf("1. ADDITION\n");
printf("2. SUBTRACTION\n");
printf("3. MULTIPLICATION\n");
printf("4. DIVISION\n");
printf("5. SAVE PREVIOUS\n");
printf("6. LOAD SAVE\n");
printf("7. QUIT\n");
// printf("8. DEBUG\n");
// printf("5. ADVANCED OPERATIONS\n"); // TODO
printf("PLEASE SELECT YOUR OPTION.\n");
scanf("%d", &option);
if(option == 1)
addition();
else if(option == 2)
subtraction();
else if(option == 3)
multiplication();
else if(option == 4)
division();
else if(option == 5)
savedata();
else if(option == 6)
loaddata();
else if(option == 7)
exit(1);
//else if(option == 8)
//debug();
else
printf("INVALID RESPONSE\n");
} // uncomment this line for infinite looping
return 0;
}
I checked using the function I wrote called debug to see if the results of the previous math problem were being put in the variable correctly and they were. This leads me to the conclusion that it is something with the way the save or load code is written that is causing this issue. Also to note, I have previously gotten char data to save, but only when it was predefined with the char data_out variable written as char data_out[]. Any information on this issue helps, thanks!

How to execute the second function in C?

Whenever I enter the choice of 2, it does not execute the view_list() function. Instead it start it from first function which is new_acc(). Also the else is not working. How to solve this problem?
#include <stdio.h>
#include <stdlib.h>
int new_acc();
int view_list();
int main(){
int one=1, two=2;
int new_account, list;
printf("%d. Create new account\n",one);
printf("%d. View customers list\n",two);
printf("Enter you choice: ");
if (scanf("%d",&one)){new_account = new_acc();} // calling a function
else if (scanf("%d",&two)){list = view_list();} // calling a function
else {printf("Sorry this is not the correct option"); break;}
return 0;
}
int new_acc(){
char name;
printf("Enter your name: ");
scanf("%s",&name);
return 0;
}
int view_list(){
printf("view list");
return 0;
}
The return value of scanf() is the number of values it returns, not the actual value it self. Code should be:
int value = 0;
scanf("%d",&value);
if(value == one){new_account = new_acc();}
else if (value == two){list = view_list();}
else {printf("Sorry this is not the correct option"); break;}
Other recommendations:
The final break is not doing anything;
Indent your code it makes it much easier to read:
int value =0;
scanf("%d",&value);
if(value == one)
{
new_account = new_acc();
}
else if (value == two)
{
list = view_list();
}
else
{
printf("Sorry this is not the correct option");
}
The return value of scanf() is number of data read.
printf("Enter you choice: ");
if (scanf("%d",&one)){new_account = new_acc();} // calling a function
else if (scanf("%d",&two)){list = view_list();} // calling a function
else {printf("Sorry this is not the correct option"); break;}
should be like
printf("Enter you choice: ");
if (scanf("%d",&one)) != 1) { puts("input read error"); return 1; }
if (one == 1){new_account = new_acc();} // calling a function
else if (one == 2){list = view_list();} // calling a function
else {printf("Sorry this is not the correct option"); return 1;}
or
printf("Enter you choice: ");
if (scanf("%d",&one)) != 1) { puts("input read error"); return 1; }
switch (one) {
case 1: new_account = new_acc(); break; // calling a function
case 2: list = view_list(); break; // calling a function
default: printf("Sorry this is not the correct option"); break;
}
By the way, executing your new_acc() is dangerous.
%s specifier will accepts positive-length string while your buffer has space for only one character.
Even input of one-character string will cause buffer overrun because there will be terminating null character.
It should be like
int new_acc(){
char name[1024]; /* allocate an array */
printf("Enter your name: ");
scanf("%1023s",name); /* specify length limit (buffer size - 1 (terminating null character)) to avoid buffer overrun */
return 0;
}

My basic trade program in C does not store any modifications when I close command prompt

#include<stdio.h>
int main() {
//After selling and buying i want it to modify this
struct music {
int srno;
char name[10];
int upperlimit;
int lowerlimit;
int avarn;
};
//Structure to maintain personal data
struct custormer {
int srno;
char name[5];
int upperlimit;
int lowerlimit;
int avarn;
};
FILE *f1;
int choice,amount,price;
int x,code,j=0;
struct music m1[] = {1,"Apple",100,98,10,2,"Valve",100,98,10,3,"Google",90,80,10,4,"Tesla",100,98,10};
struct music m2[10];
f1 = fopen("4.DAT","rb+");
if(f1==NULL)
{
printf("File does not exist!");
exit(0);
}
while(1)
{
printf("___________________________________\n");
printf("MENU\n");
printf("___________________________________\n");
printf("1) Stock Market\n");
printf("2) Buy\n");
printf("3) Personal Info\n");
printf("4) Sell\n");
printf("5) Exit\n");
printf("Enter choice:");
scanf("%d",&choice);
switch(choice)
{
case 1:
{
printf("Stock Market\n");
printf("___________________________________\n");
for(x=0;x<4;x++)
{
printf("%d\t %s\t %d\t %d\t %d\n",m1[x].srno,m1[x].name,m1[x].upperlimit,m1[x].lowerlimit,m1[x].avarn);
fwrite(&m1,sizeof(m1),1,f1);
}
break;
}
case 2:
{
printf("Enter code of Stock:");
scanf("%d",&code);
printf("Enter number of stocks:");
scanf("%d",&amount);
printf("Enter price:");
scanf("%d",&price);
rewind(f1);
for(x=0;x<4;x++)
{
if(price>m1[x].lowerlimit&&price<m1[x].upperlimit)
{
if(m1[x].srno==code)
{
printf("Trasaction Is Succesful\n");
m1[x].avarn = m1[x].avarn-amount;
fwrite(&m1,sizeof(m1),1,f1);
m2[j].srno = j+1;
strcpy(m2[j].name,m1[x].name);
m2[j].avarn = amount;
j++;
}
}
}
break;
}
case 3:
{
for(x=0;x<j;x++)
{
printf("%d\t %s\t %d\n ",m2[x].srno,m2[x].name,m2[x].avarn);
fseek ( f1, sizeof(m1), SEEK_CUR ) ;
fwrite ( &m2, sizeof(m2), 1, f1 ) ;
}
break;
}
case 4:
{
printf("Enter code of stock to sell:");
scanf("%d", &code);
printf("Enter amount to sell:");
scanf("%d",&amount);
printf("Enter price to sell:");
scanf("%d",&price);
for(x=0;x<4;x++)
{
if(price>m1[x].lowerlimit&&price<m1[x].upperlimit)
{
if(m1[x].srno==code)
{
printf("Transaction is Sucessful\n");
m1[x].avarn = m1[x].avarn+amount;
fwrite(&m1,sizeof(m1),1,f1);
}
}
}
break;
}
case 5:
{
printf("Thanks!");
exit(0);
}
default:
{
printf("Invalid input!");
exit(0);
break;
}
}
}
fclose(f1);
return 0;
}
The program will execute and run but it will not store any data that I add when I buy or sell stocks, I'm still learning file operations, can someone correct this program or tell me how to do it? I feel like the fwrite() function is maybe not taking in the values I'm giving it The program will execute and run but it will not store any data that I add when I buy or sell stocks, I'm still learning file operations, can someone correct this program or tell me how to do it? I feel like the fwrite() function is maybe not taking in the values I'm giving it
You are using the wrong operator for testing equality.
if(f1=NULL)
This statement will assign NULL to f1, which will then evaluate to false.
You should use if (f1 == NULL) to test if it's NULL. Or just simply if (f1).
Something else strange that you are doing is opening the file twice, leaking the first handle. You should close it first, or open it only once.
Also, you should pay attention to the open mode. Your second call will actually destroy the file's contents. Read the documentation.

Reading a binary file and show the entries [closed]

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 5 years ago.
Improve this question
I may need your help to solve this issue...
I'm learning about C and find a problem, how to properly read a binary file.
I have a struct array filled, then wrote on binary file and try to read it, but this isn't show nothing.
The code is in pastebin
My code
#include <stdio.h>
#include <ctype.h>
#include <math.h>
typedef struct {
int id;
char name[100];
char document[14];
float testGrade;
} Candidate;
typedef struct {
int id;
float testGrade;
} Grade;
FILE * openFile(char filename[100], char filemode[3]) {
FILE *p = fopen(filename, filemode);
if (!p) {
printf("Error to open %s file. \nThe program will be closed.",filename);
exit(1);
}
}
void addCandidate(int newId, int numbersOfNewCandidate, char candidateFilename[100], char gradeFilename[100]) {
int counter = 0;
float testGrade = 0;
Candidate*candidate;
candidate= malloc(sizeof(Candidate) * numbersOfNewCandidate);
Grade *grade;
grade= malloc(sizeof(Grade) * numbersOfNewCandidate);
for(;counter< numbersOfNewCandidate; counter++) {
system("#cls||clear");
printf("Adding #%d:",newId);
printf("\n---------------\n");
printf("\nName of candidate: ");
gets(&candidate[counter].name);
printf("\nDocument: ");
gets(&candidate[counter].document);
do {
printf("\nTest grade (between 0 and 10): ");
scanf("%f",&testGrade);
printf("\n---------------\n");
if (testGrade < 0 || testGrade > 10) {
printf("\nERROR!\nTest grade %.2f invalid, please try again with a grade between 0 and 10.\n",testGrade);
}
} while(testGrade < 0 || testGrade > 10);
candidate[counter].id = newId;
grade[counter].id = newId;
candidate[counter].testGrade = testGrade;
grade[counter].testGrate = testGrade;
newId++;
fflush(stdin);
}
FILE *candidateFile = openFile(candidateFilename, "a+b");
fwrite(candidate, sizeof(candidate),numbersOfNewCandidate, candidateFile );
FILE *gradeFile = openFile(gradeFilename, "a+b");
fwrite(grade, sizeof(grade),numbersOfNewCandidate, gradeFile );
fclose(candidateFile);
fclose(gradeFile);
free(candidate);
free(grade);
}
void showCandidate(int typeOfSearch, char valueToSearch[100]) {}
void listAllCandidates(char candid[100]) {
FILE *fp = openFile(candidateFilename, "rb");
//fseek(fp,0,SEEK_SET);
Candidate *candidate = NULL;
candidate = malloc(sizeof(Candidate) + 1);
while(fread(&candidate,sizeof(Candidate),1,fp) == 1) {
printf("\n\nId: %d \nName: %s \nDocument: %s \nGrade: %.2f",candidate->id,candidate->name,candidate->document, candidate->testGrade);
}
getche();
free(candidate);
}
void main(){
int lastId = 0;
char candidateFilename[100] = "candidates.bin";
char gradeFilename[100] = "classificationList.bin";
char option;
do {
system("#cls||clear");
printf("Menu: \n");
printf("1 - Add candidates \n");
// printf("2 - Search by name \n");
// printf("3 - Search by document \n");
// printf("---------------------------\n");
// printf("4 - Show Max Grade, Minimum, Avg \n");
printf("5 - List candidates \n");
printf("6 - Erase files \n");
printf("---------------------------\n");
printf("S - Exit \n");
printf("\n\n");
option = toupper(getche());
switch(option) {
case '1':
system("#cls||clear");
int numbersOfNewCandidate = 0;
int newId = 0;
printf("Home > Add candidates\n\n");
printf("Please give the number of new candidates: ");
scanf("%d",&numbersOfNewCandidate);
newId = lastId;
lastId += numbersOfNewCandidate;
fflush(stdin);
addCandidate(newId + 1, numbersOfNewCandidate, candidateFilename, gradeFilename);
printf("\n\nAdding new candidates: Finished \n");
break;
// case '2':
// printf("\noption %c#\n",option);
// break;
// case '3':
// printf("\noption %c#\n",option);
// break;
// case '4':
// printf("\noption %c?\n",option);
// break;
case '5':
listAllCandidates(candidateFilename);
break;
case '6':
remove(candidateFilename);
remove(gradeFilename);
printf("\nRemoved!!\n");
break;
case 'S':
printf("\noption %c, the program will be ended...\n",option);
break;
default:
printf("\nWrong option!!\n");
break;
}
} while (option != 'S');
}
Please, if you find other issues about my code, try to elucidate me about it..
I already tryed it too, but nothing yet.
while(!feof(fp)) {
fread(&candidate,sizeof(Candidate),1,fp);
printf("\n\nId: %d \nName: %s \nDocument: %s \nGrade: %.2f",candidate->id,candidate->name,candidate->document, candidate->testGrade);
}
Candidate *candidate = NULL;
candidate = malloc(sizeof(Candidate) + 1);
while(fread(&candidate,sizeof(Candidate),1,fp) == 1) {...}
free(candidate);
The first parameter in fread should be a pointer fread(void*,...), and candidate is already declared as a pointer, it should not have a reference operator. The correct usage is:
while(fread(candidate,sizeof(Candidate),1,fp) == 1) {...}
Note that there is no reference & operator in front of candidate
Sometime you see a reference operator, but that's a different case like this:
Candidate cand;
while(fread(&cand,sizeof(cand),1,fp) == 1) {...}
This is an easier method because cand does not need to be allocated with malloc and it does not need free
Unnecessary functions introduce more errors:
FILE * openFile(char filename[100], char filemode[3]) {
FILE *p = fopen(filename, filemode);
if (!p) {
printf("Error to open %s file. \nThe program will be closed.",filename);
exit(1);
}
}
This function is supposed to return a file pointer. Also function parameter can be simply written as const char* filename and const char *filemode. Example:
FILE * openFile(const char* filename, const char* filemode) {
FILE *p = fopen(filename, filemode);
if (!p) printf("Error to open %s file. \nThe program will be closed.",filename);
return p;
}
I would get rid of this function altogether because it's basically useless. Just use fopen. Make sure to close the handle with fclose when you are done.
grade[counter].testGrate = testGrade;
^
This is a typo, it should be grade[counter].testGrade. It is recommended to compile the program with warning level set to maximum, or at least set to level 4. The compiler will tell about about the typos, errors and warnings. You have to be able to compile the program with zero errors and zero warnings. Here is a simple version:
void listAllCandidates(char* candidateFilename)
{
FILE *fin = fopen(candidateFilename, "rb");
Candidate cand;
while(fread(&cand, sizeof(cand), 1, fin))
printf("%s, %s, %d, %f\n", cand.name, cand.document, cand.id, cand.testGrade);
fclose(fin);
}
int main()
{
char candidateFilename[] = "file.bin";
FILE *fout = fopen(candidateFilename, "ab");
Candidate cand;
strcpy(cand.name, "name1");
strcpy(cand.document, "document1");
cand.id = 1;
cand.testGrade = 1.1f;
fwrite(&cand, sizeof(cand), 1, fout);
strcpy(cand.name, "name2");
strcpy(cand.document, "document2");
cand.id = 2;
cand.testGrade = 2.2f;
fwrite(&cand, sizeof(cand), 1, fout);
fclose(fout);
listAllCandidates(candidateFilename);
printf("\n");
return 0;
}

Resources