I am facing an issue with the last part of the assignment. I want to update(modify) the specific value in a text file but this program stop working from the if statement in the while loop. I have tried to fix this issue but I couldn't figure it out. Please help.
int Equant()
{
DisplayList();
FILE * fpr_r = fopen("donation.txt", "r");
FILE * fpr_w = fopen("Edonation.txt", "w");
if (fpr_r == NULL || fpr_w == NULL)
{
printf ("An able to open the file for writing");
exit(1);
}
int Inumber, v=0;
double NQuant, NVQuant;
struct Donate Esearch;
printf ("\nEnter the ID you want to change the quantity: ");
scanf ("%d", &Inumber);
while (fread(&Esearch, sizeof(struct Donate),1,fpr_r))
{
fscanf (fpr_r,"%d %s %s %s %d %lf,", &Esearch.IDd, &Esearch.supply, &Esearch.Scode, &Esearch.Cdonator, &Esearch.Nship, &Esearch.QuantityR);
if (Esearch.IDd == Inumber)
{
printf ("ID: %d Name of Supply: %s, Supply Code: %s, Donator: %s, No. of Shipment: %d, Quantity Received (Million): %lf\n",
Esearch.IDd, Esearch.supply, Esearch.Scode, Esearch.Cdonator, Esearch.Nship, Esearch.QuantityR);
printf ("\nEnter the new Quantity value: ");
scanf ("%lf", &NVQuant);
Esearch.QuantityR = NVQuant;
}
fwrite (&Esearch, sizeof(struct Donate),1,fpr_w);
}
fclose(fpr_r);
fclose(fpr_w);
if (!v)
{
printf ("No line founded.\n");
}
Related
I have this program where I can input the number of students, their names, and their corresponding grades for prelims, midterms, and finals. All of these user inputted data will be put on a text file.
I tried to create an edit function to update a specific line that contains a student's name and grades on the text file.
But instead of replacing it with newly updated data, it deletes it.
Here's my source code for the write function and getScore function, which will allow the user to input data (such as student name and grades) to the text file:
#define max 256
void write()
{
system("cls");
printf("\n Enter the number of students: ");
scanf("%d", &numberOfStudents);
FILE *fp;
fp = (fopen("studentRecord.txt", "a"));
if (fp == NULL)
{
printf("\n Error!");
exit(1);
}
fprintf(fp, " Name \t \t Prelims \t Midterms \t Finals \t Average \t Rating \n");
for (i = 0; i < numberOfStudents; ++i)
{
printf("\n Student No. %d ", i + 1);
getScore(studentName, &prelims, &midterms, &finals);
/******This is just another function for computing the average scores******/
averageScores = average(prelims, midterms, finals);
/******This is just also another function for rating the average scores******/
rating = rate(averageScores);
fprintf(fp, " %d.) %s \t %d \t \t %d \t \t %d \t \t %.2f \t \t %.2f \n", i + 1, studentName, prelims, midterms, finals, averageScores, rating);
}
fclose(fp);
printf("\n \n File studentRecord.txt is saved!");
getch();
view();
}
void getScore(char *studentName, int *prelims, int *midterms, int *finals)
{
printf("Name: ");
scanf("%s", studentName);
printf("\n \t Prelims: ");
scanf("%d", prelims);
printf("\n \t Midterms: ");
scanf("%d", midterms);
printf("\n \t Finals: ");
scanf("%d", finals);
}
Here's my source code for the edit function, which should allow the user to edit a specific line on the text file:
void edit()
{
system("cls");
FILE *fpo;
FILE *fp2;
int lno, linectr = 0;
char str[max];
char newln[max], temp[] = "temp.txt";
printf("\n Input the file to be opened: ");
fgets(file_name, max, stdin);
file_name[strlen(file_name) - 1] = '\0';
fpo = fopen(file_name, "r");
if (!fpo)
{
printf("\n Unable to open the input file!");
main();
}
fp2 = fopen(temp, "w");
if (!fp2)
{
printf("\n Unable to open a temporary file to write!");
fclose(fpo);
main();
}
printf("\n Input the line number you want to update: ");
scanf("%d", &lno);
printf("\n Student No. %d ", lno);
getScore(studentName, &prelims, &midterms, &finals);
averageScores = average(prelims, midterms, finals);
rating = rate(averageScores);
fprintf(fp, " %d.) %s \t %d \t \t %d \t \t %d \t \t %.2f \t \t %.2f \n", lno, studentName, prelims, midterms, finals, averageScores, rating);
lno++;
while (!feof(fpo))
{
strcpy(str, "\0");
fgets(str, max, fpo);
if (!feof(fpo))
{
linectr++;
if (linectr != lno)
{
fprintf(fp2, "%s", str);
}
else
{
fprintf(fp2, "%s", newln);
}
}
}
fclose(fpo);
fclose(fp2);
remove(file_name);
rename(temp, file_name);
getch();
view();
}
When compiled and run, it goes like this:
These are the user inputted data in the text file
And this is when I try to update line number 3's data
Lastly, this is when I try to view to updated contents of the text file that should've included the new data.
The line that should've been updated is rather deleted.
Please check my code if there's anything wrong with it. It would be a great help someone pointed out the error
The copying loop uses feof() to try and detect end of file, but this method is incorrect: you should just use the return value of fgets(), which will be a null pointer if no line could be read from the file.
while (fgets(str, max, fpo)) {
linectr++;
if (linectr == lno) {
fputs(newln, fp2);
} else {
fputs(str, fp2);
}
}
For further explanations, read Why is “while ( !feof (file) )” always wrong?
Note also that you should use snprintf instead of fprintf to compose the new line contents:
sprintf(newln, sizeof newln, " %d.) %s \t %d \t \t %d \t \t %d \t \t %.2f \t \t %.2f \n",
lno, studentName, prelims, midterms, finals, averageScores, rating);
The line number should not be updated either: remove the lno++; statement.
Case study 8 – Develop a Hospital Management System Write C programs to
Store the patient details in to a text file.
View the details of patients using phone number, NIC , etc…
Store the patient channeling details to another text file.
Display the summary of the patients.
create 4 seperate c programs covering all sections.
Can someone please help me because I don't get an output for section 2 and 4. section 1 and 3 works fine. All for sections are interconnected I guess.
**This is the code I created for section 1:
#include<stdio.h>
int main(void)
{
int pnum,age,cnum,nic;
char name[20],gender[6],address[50];
FILE * fp;
fp = fopen("patient.txt", "a");
printf("Add patient details\n\n");
printf("Patient number: ");
scanf("%d", &pnum);
printf("First name: ");
scanf(" %s", &name);
printf("Gender: ");
scanf(" %s", &gender);
printf("Age: ");
scanf("%d", &age);
printf("Address: ");
scanf(" %s", &address);
printf("NIC: ");
scanf("%d", &nic);
printf("Contact number: ");
scanf("%d", &cnum);
fprintf(fp, "%d %s %s %d %s %d %d\n", pnum, name, gender, age, address, nic, cnum);
fclose(fp);
return 0;
}
**This is the code I created for section 2:
#include<stdio.h>
int main(void)
{
int pnum,age,cnum,nic;
char name[20],gender[6],address[50];
FILE * fp;
fp = fopen("patient.txt", "r");
if ( fp != NULL)
{
while(!feof(fp))
{
fscanf(fp, "%d %s %s %d %s %d %d", pnum, name, gender, age, address, nic, cnum);
printf("%d %s %s %d %s %d %d", pnum, name, gender, age, address, nic, cnum);
}
fclose(fp);
}
else
{
printf("could not open file\n");
}
return 0;
}
**This is the code for section 3:
#include <stdio.h>
int main(void)
{
int pnum,chnum,nic;
char name[20],doc[20],sickness[50];
FILE * fp1;
fp1 = fopen("channeling.txt", "a");
printf("Add patient channeling details\n\n");
printf("Patient number: ");
scanf("%d", &pnum);
printf("Channeling number: ");
scanf("%d", &chnum);
printf("First name: ");
scanf(" %s", &name);
printf("NIC: ");
scanf("%d", &nic);
printf("Sickness: ");
scanf(" %s", &sickness);
printf("Prescribed doctor: ");
scanf(" %s", &doc);
fprintf(fp1, " %d %d %s %d %s %s\n", pnum, chnum, name, nic, sickness, doc);
fclose(fp1);
return 0;
}
**This is the code for section 4:
#include<stdio.h>
int main(void)
{
int pnum,age,cnum,nic;
char name[20],gender[6],address[50];
FILE * fp;
fp = fopen("patient.txt", "r");
if ( fp != NULL)
{
while(!feof(fp))
{
fscanf(fp, "%d %s %s %d %s %d %d", pnum, name, gender, age, address, nic, cnum);
printf("%d %s %s %d %s %d %d", pnum, name, gender, age, address, nic, cnum);
}
fclose(fp);
}
else
{
printf("could not open file\n");
}
return 0;
}
Problems are:
while (!feof(fp) feof indicates an error has occurred. So the logic in your program is not correct. (if fscanf does get an error, printf will still get executed)
Forgot & in fscanf.
This question already has answers here:
How do I properly compare strings in C?
(10 answers)
Closed 6 years ago.
This is a part of my 'Phonebook' program.
void viewone(){
char name[25], fname[25];
int n, ncheck, op;
fp = fopen("Phonebook.txt","r");
printf ("\n Search by : \n 1: Name\n 2: Phone Number\n");
printf ("Enter option : ");
scanf ("%d",&op);
switch(op){
case 1:
printf ("\n Enter Name : ");
scanf ("%s",name);
fscanf(fp, "%s %d", fname, &ncheck);
while (!feof(fp)){
printf ("\n\n %s \n\n",fname);
if (fname == name){ \\ Problem in here
printf ("\n\n Contact Found...\n");
printf (" %s +880%d", fname, ncheck);
break;
}
else{
fscanf(fp, "%s %d", fname, &ncheck);
}
if (feof(fp)){
printf ("\n\n Contact Not Found...\n\n");
}
}
menu();
break;
case 2:
printf ("\n\n Enter Contact Number (+880) : ");
scanf ("%d",&n);
fscanf(fp, "%s %d", fname, &ncheck);
while (!feof(fp)){
if (ncheck == n){
printf ("\n\n Contact Found...\n");
printf (" %s +880%d\n", fname, ncheck);
break;
}
else{
fscanf(fp, "%s %d", fname, &ncheck);
}
if (feof(fp)){
printf ("\n\n Contact Not Found...\n\n");
}
}
menu();
break;
default:
printf ("\n Wrong option...\n\n");
viewone();
break;
}
}
When it comes to the marked line, the program should search the file for the 'fname' character until it matches the 'name' character. But though they match, nothing happens and the program still goes on. And in the end, it does what is told in the else statement. My question is why is this happening and how can i fix it?
My program runs perfectly when i search with phone number. But why is it not happening with character?
Comparing string is not done by ==. Instead use string compare function like this
strcmp(fname,name)
student.dat file
----------------
Stu:1 abc ($) - 55 in following order (Stu: %d %s (%c) - %d)
Stu:2 pqr (^) - 82
I am trying to read this file and save highest grade details in the variable in c programming.
my code is below but is not complete!
int main(){
int num, grade;
char id, name[35];
FILE *fp = NULL;
fp = fopen("student.dat", "r");
if (fp != NULL) {
while ((fp != '\n') && (fp != EOF)) {
fscanf(fp, "%d %s %c %d", &num, name, id, &grade);
printf("Student Num: %d", num);
printf("Student Name: %s", name);
printf("Student id: %c", id);
printf("Student grade: %d", grade);
}
fclose(fp);
}else {
printf("Failed to open file\n");
}
}
In C, you have 2 primary ways to read line-oriented input and then parse into individual values (really 3, but we will ignore walking a pair of pointers down the string for now).
The preferred manner is to use a line-oriented input function such as fgets or POSIX getline to read an entire line into a buffer, and then parse the buffer with sscanf which can be done in a more flexible manner than a single call to fscanf.
Nonetheless, you appear dedicated to using fscanf here. The key to using fscanf successfully is to provide a format string that accounts for all characters in the line to be read, or to craft the format string to take advantage of properties of the individual format specifiers to accomplish the same thing (e.g. %s (as well as your numerical conversions) will skip leading whitespace giving you some control to deal with line-endings that would otherwise be left in the input-buffer (either the file or stdin and therefore be the next character available on a subsequent call to fscanf, which if not properly handled, will throw a wrench into your read routine.
Another mandatory step is to validate that all conversions specified were successfully completed during each read. You do that by checking the return value for fscanf which is the match count (a count of the number of successful conversions that took place). If you do not check, you cannot have any type of confidence that your values actually hold the data you think they do.
Putting that together, using your input file, and taking the filename to open as the first argument to the program (and reading by default on stdin if no filename is given), you could do something like the following:
#include <stdio.h>
int main (int argc, char **argv) {
int num =0, grade = 0, max = 0; /* initialize all variables */
char id = 0, name[35];
const char *fmt = " Stu:%d %s (%c) - %d"; /* given format string */
FILE *fp = NULL;
if (!(fp = argc > 1 ? fopen (argv[1], "r") : stdin)) {
fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
return 1;
}
/* read each line and validate 4 successful conversions */
while (fscanf (fp, fmt, &num, name, &id, &grade) == 4) {
if (grade > max) max = grade;
printf ("Student Num: %d Name: %-12s id: %c grade: %d\n",
num, name, id, grade);
}
printf ("\n highest grade : %d\n\n", max);
if (fp != stdin) fclose (fp);
return 0;
}
Example Use/Output
$ ./bin/stdntread <dat/stdntread.dat
Student Num: 1 Name: abc id: $ grade: 55
Student Num: 2 Name: pqr id: ^ grade: 82
highest grade : 82
Look over the code, and especially the slight tweak to the format specifier, and let me know if you have any additional questions.
As user3386109 already hinted at: the format string "Stu: %d %s (%c) - %d" should do it. It actually doesn't, you need to add the newline, too.
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
int main()
{
int num, grade, ret;
char id, name[35];
int lineno = 1;
FILE *fp = NULL;
// reset errno, just in case
errno = 0;
fp = fopen("student.dat", "r");
if (fp != NULL) {
for (;;) {
ret = fscanf(fp, "Stu: %d %s (%c) - %d\n", &num, name, &id, &grade);
if (ret != 4 && ret != EOF){
fprintf(stderr,"fscanf() returned %d instead of 4 for line %d\n",ret,lineno);
// unlikely, but cheap to check, so check
if(errno != 0){
fprintf(stderr,"With error %s\n",strerror(errno));
}
exit(EXIT_FAILURE);
}
if (ret == EOF) {
// fscanf() returns EOF for end-of-file _and_ error.
// check for error first
if(errno != 0){
fprintf(stderr,"The error %s occured while reading line %d\n",strerror(errno), lineno);
exit(EXIT_FAILURE);
}
// we are done with the file at this point and can bail out graciously
break;
}
printf("Student Num: %d, ", num);
printf("Student Name: %s, ", name);
printf("Student id: %c, ", id);
printf("Student grade: %d\n", grade);
lineno++;
}
fclose(fp);
} else {
printf("Failed to open file: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
File student.dat generated with
for i in `seq 1 1 100`;do character=$(printf \\$(printf '%03o' $((`shuf -i 40-99 -n 1`))));name=$(cat /dev/urandom | tr -dc 'a-zA-Z' | fold -w 3 | head -n 1); echo Stu:$i $name \($character\) - `shuf -i 10-99 -n 1`;done > student.dat
(Yes, that generation can be done simpler, I'm pretty sure ;-) )
First 10 lines of input (new-line is \n everywhere):
Stu:1 qim (+) - 13
Stu:2 EcF (L) - 61
Stu:3 Ko1 (Q) - 50
Stu:4 Ve7 (,) - 23
Stu:5 NiX (;) - 28
Stu:6 4O8 (C) - 73
Stu:7 00m (]) - 79
Stu:8 uiw (C) - 45
Stu:9 47k (X) - 80
Stu:10 MmJ (A) - 38
(file ends with new-line \n!)
Your while loop have incorrect condition, it'll never become false, File pointer never reaches to \n nor EOF, I had modified your code and now its working properly. Check while condition in code
int num, grade;
char id, name[35];
FILE *fp = NULL;
fp = fopen("student.dat", "r");
if (fp != NULL) {
int ret;
while((ret = fscanf(fp, "%d %s %c %d", &num, name, &id, &grade))!=EOF)
{ printf(" Student Num: %d", num);
printf(" Student Name: %s", name);
printf(" Student id: %c", id);
printf(" Student grade: %d\n", grade);
}
fclose(fp);
}else {
printf("Failed to open file\n");
}
int main() {
scanf("%d",&a);
while(1) {
switch(a) {
case 0:
exit(0);
case 1:
fp = fopen("info.txt", "r");
if (fp == NULL)
printf("File doest not exist! \n");
else {
for(i=0; !feof(fp); i++) {
fscanf(fp, "%s %s %s %s %s %s",
user[i].name,
user[i].surname,
user[i].gender,
user[i].status,
user[i].education,
user[i].adress);
printf("%s, %s, %s, %s, %s, %s\n",
user[i].name,
user[i].surname,
user[i].gender,
user[i].status,
user[i].education,
user[i].adress);
fclose(fp);
}
}
break;
case 2:
for(i=0; i<N; i++) {
printf("\nUser application data\n", i+1);
printf("Name: ");
gets(user[i].name);
gets(user[i].name);
printf("Surname: ");
gets(user[i].surname);
printf("Gender: ");
gets(user[i].gender);
printf("Status: ");
gets(user[i].status);
printf("Education: ");
gets(user[i].education);
printf("Adress: ");
gets(user[i].adress);
fp = fopen("info.txt", "a");
fprintf(fp, "\n%s %s %s %s %s %s",
user[i].name,
user[i].surname,
user[i].gender,
user[i].status,
user[i].education,
user[i].adress);
fclose(fp);
}
}
}
}
Ok, so I'm kinda lost right now. Case 2 where I add strings to text file works flawlessly, but when when I want to check out the added data to the text file using the case 1, program crashes, so far Ive tried several things and no improvements. Would be very thankful for some help!
In case 1: you are fclose-ing every time you loop which means that after the first loop it will close the file then when it tries to feof and fscanf in the next loop the program will fail.