Hi I have trying to merge two text files alternatively in a way that I get one line from first file and then I get second line from the next one, please help me, spent way too much time on this and still cannot get anything on the new file. Code is given below.
#include<stdio.h>
#include<stdlib.h>
int main()
{
FILE *pointer1, *pointer2, *pointer3;
char source1[80],source2[80],target[80];
char ch1,ch2;
printf("Enter the source and source 2\n");
scanf("%s %s", source1,source2);
printf("Enter the destination\n");
scanf("%s",target);
pointer1 = fopen(source1,"r");
pointer2 = fopen(source2,"r");
pointer3 = fopen(target,"w");
if(pointer1 == NULL || pointer2==NULL || pointer3==NULL)
{
printf("Cannot open a file\n ");
exit(1);
}
while(1)
{
if(ch1!=EOF)
{
ch1 = fgetc(pointer1);
while(ch1!='\n')
{
if(ch1==EOF)
break;
fputc(ch1,pointer3);
ch1=fgetc(pointer1);
}
}
if(ch2!=EOF)
{
ch2=fgetc(pointer2);
while(ch2!='\n')
{
if(ch2==EOF)
break;
fputc(ch2,pointer3);
ch2=fgetc(pointer2);
}
}
if(ch1==EOF && ch2==EOF)
break;
}
printf("Merging completed successfully\n");
printf("Press any key to exit\n");
getch();
}
Related
Hi I tried the same using fgets but the result are very different, I am able to achieve it through fgetc but not using fgets, what am I doing wrong. Somehow while merging a line is skipped, for instance it copies 1st file from each file and then skips to the 3rd line.
#include<stdio.h>
#include<stdlib.h>
#include<strings.h>
int main()
{
FILE *pointer1, *pointer2, *pointer3;
char source1[80],source2[80],target[80];
char str1[80],str2[80];
printf("Enter the source and source 2\n");
scanf("%s %s", source1,source2);
printf("Enter the destination\n");
scanf("%s",target);
pointer1 = fopen(source1,"r");
pointer2 = fopen(source2,"r");
pointer3 = fopen(target,"w");
if(pointer1 == NULL || pointer2==NULL || pointer3==NULL) {
printf("Cannot open a file\n ");
exit(1);
}
while(1) {
if(fgets(str1,79,pointer1)!=NULL) {
fputs(str1,pointer3);
}
if(fgets(str1,79,pointer1)==NULL)
break;
if(fgets(str2,79,pointer2)!=NULL) {
fputs(str2,pointer3);
}
if(fgets(str2,79,pointer2)==NULL)
break;
}
fclose(pointer1);
fclose(pointer2);
fclose(pointer3);
printf("Merging completed successfully\n");
printf("Press any key to exit\n");
getch();
}
The unexpected behaviour you are getting is actually very expected.
Even if you are, in your mind, just testing if the file is not done yet, eg: if(fgets(..) != NULL), that function actually extracts that line from a file and loses it, since you don't do anything with it.
First, I have two mentions:
At least on my computer, you need to include "conio.h" for the getch function, so I don't know how it compiles on your PC.
For future reference, please check a coding-style guide, because there are very many mistakes. Try this link: https://users.ece.cmu.edu/~eno/coding/CCodingStandard.html. For a simpler method, just search on google: "C code beautify" and they will take care of the coding style the code for you.
I'll help you with a solution here, but, to not make it too easy, I've also slipped a little mistake.
#include<stdio.h>
#include<stdlib.h>
#include<strings.h>
#include<conio.h>
int main() {
FILE *pointer1, *pointer2, *pointer3;
char source1[80], source2[80], target[80];
char str1[80], str2[80];
printf("Enter the source and source 2\n");
scanf("%s %s", source1, source2);
printf("Enter the destination\n");
scanf("%s", target);
pointer1 = fopen(source1, "r");
pointer2 = fopen(source2, "r");
pointer3 = fopen(target, "w");
if (pointer1 == NULL || pointer2 == NULL || pointer3 == NULL) {
printf("Cannot open a file\n ");
exit(1);
}
int end_first_file = 0;
int end_second_file = 0;
while (1) {
if (fgets(str1, 79, pointer1) != NULL && end_first_file == 0) {
fputs(str1, pointer3);
} else {
end_first_file = 1;
}
if (fgets(str2, 79, pointer2) != NULL && end_second_file == 0) {
fputs(str2, pointer3);
} else {
end_second_file = 1;
}
if(end_second_file && end_first_file)
break;
}
fclose(pointer1);
fclose(pointer2);
fclose(pointer3);
printf("Merging completed successfully\n");
printf("Press any key to exit\n");
getch();
}
The mistake that I've told you about, that I'm having you solve, is the following:
Taking as example:
Source1:
aa
aaa
Source2:
bb
bbb
bbbb
You will get the output:
aa
bb
aaabbb
bbbb
Q1: What happened there? "aaabbb".
Q2: How do you solve it?
Kind regards,
Claudiu
I can't get my delete record function to break out of the switch case or even give me an error when the record doesn't exist. Could someone please tell me why this is?
Any help is much appreciated!
I can't get my delete record function to break out of the switch case or even give me an error when the record doesn't exist. Could someone please tell me why this is?
Any help is much appreciated!
void delete_record();
void displayContent();
struct Update
{
char studentName[50];
char studentID [50];
char emailID[100];
char courseID[5];
char grade[50];
} update2;
int main ()
{
int num;
do
{
printf("1. Delete a record for the specific name\n");
printf("2. Display Content of File\n");
printf("6. Exit\n");
switch(num)
{
case 1:
printf("this is a test\n");
delete_record();
break;
//displayContent();
//printf("this is a test 2\n");
case 2:
printf("\n\nDiplaying Contents of File\n\n");
displayContent();
default:
printf("Give me a break!\n");
break;
}
scanf("%d", &num);
} while (num != 6);
return 0;
}
void delete_record()
{
FILE *fp;
FILE *fp_tmp;
fp = fopen ("BINARY_FILE.txt", "w");
char studentsID[20];
printf("enter studentID to delete:");
scanf("%s",studentsID);
printf("is this a test?\n");
while(fread(&update2,sizeof(update2),1,fp))
{
printf("this is another test\n");
if(strcmp(update2.studentID,studentsID) != 0)
{
//printf("testing\n");
fwrite(&update2,sizeof(update2),1,fp);
}
else
{
printf("No student with that student ID\n");
}
}
printf("more tests\n");
fclose(fp);
return;
}
void displayContent()
{
char c;
// Open file
FILE *fp;
fp = fopen ("BINARY_FILE.txt", "r");
if (fp == NULL)
{
printf("File Has No Content\n");
exit(0);
}
// Read contents from file
c = fgetc(fp);
while (c != EOF)
{
printf ("%c", c);
c = fgetc(fp);
}
fclose(fp);
//return 0;
}
When using scanf to read from the keyboard you must remember
that all characters that you enter are written to the in-buffer,
this means that if you type in
42ENTER
The ENTER will also be present in the in-buffer, so next time you call scanf ENTER will still be in the buffer and then scanf returns 0 since the format specificier "%d" doesn't match.
The easiest way to handle input from keyboard in C and to avoid the hassle of scanf in-buffer by using fgets() to read from the keyboard, then use sscanf() to cherry pick from the buffer:
// always check return value from all runtime functions when possible
char buffer[128];
if (fgets(buffer,sizeof(buffer), stdin) != NULL)
{
if (sscanf(buffer, "%d", &num) == 1)
{
}
else {...}
}
else {...}
Noob programmer here...so please bear with me. I'm trying to pass an existing text file into an array however once my main Menu loads the information that once existed in that file goes away, even if I don't make any changes. it is just not keeping the information. The Program is supposed to allow the user to either create a new file or update and/or load an existing file. Any ideas on how to fix this issue? Thank you all!
char fileName[20] = "";
void loadEmployee()
{
FILE* fPtr;
char singleLine[150];
if (strcmp(fileName, "") == 0)
{
printf("\nWhat's the name of the file? ");
scanf_s("%s", fileName, 20);
}
fopen_s(&fPtr, fileName, "r");
while (!feof(fPtr))
{
fgets(singleLine, 150, fPtr);
puts(singleLine);
}
fclose(fPtr);
}
void saveEmployee()
{
FILE* fPtr;
if (strcmp(fileName, "") == 0)
{
printf("\nWhat's the name of the file? ");
scanf_s("%s", fileName, 20);
}
fopen_s(&fPtr, fileName, "w");
for (int i = 0; i < numEmps; i++)
{
fprintf(fPtr, "%s %f %f\n", emps[i].emps.name,
emps[i].emps.rate, emps[i].emps.hours);
}
fclose(fPtr);
}
void loadMenu()
{
int i = 0;
printf("1. Load from a file \n");
printf("2. Keyboard \n");
scanf_s("%d", &choice);
switch (choice)
{
case 1: loadEmployee();
break;
default:
break;
}
do
{
printf("\nMAIN MENU\n");
printf("1.Add Employee\n");
printf("2.Edit Employee\n");
printf("3.Print Employee\n");
printf("4.Print ALL employees\n");
printf("5.Exit\n");
scanf_s("%d", &choice);
switch (choice)
{
case 1: NameInput();
break;
case 2: printf("Choose employee: \n");
for (int i = 0; i < numEmps; i++)
{
printf("%d. %s \n", i + 1,
emps[i].emps.name);
}
scanf_s("%d", &choice);
empUpdate(choice - 1);
break;
case 3: printf("Choose employee: \n\n");
for (int i = 0; i < numEmps; i++)
{
printf("%d) %s \n", i + 1,
emps[i].emps.name);
}
scanf_s("%d", &choice);
printf("%s \n", emps[choice -
1].emps.name);
printf("%.2f \n", emps[choice -
1].emps.hours);
printf("%.2f \n", emps[choice -
1].emps.rate);
break;
case 4: PayOutput();
break;
case 5: printf("Quitting program!");
saveEmployee();
return;
default: printf("Invalid choice try again \n\n");
break;
}
} while (choice != 5);
}
int main()
{
struct information empsi[20];
loadMenu();
}
Your function loadEmployee only writes to a char[] that is local to the function (which means it’s discarded at the end).
When the program exits, you « save » the employee by reopening your file in write mode, which clears it, and what follows probably doesn’t do much, so the file remains empty.
Try actually returning or storing the data from the file outside your function so it can be reused later.
As #hugo said, the program reads the file but doesn't store the contents. This means emps will be empty. When you quit you open the file for writing deleting its contents. Beause emps is empty, nothing is written.
This can be solved by reading similar to how you're writing. I don't know exactly what emps looks like, but something like this.
for( numEmps = 1; fgets(singleLine, 150, fPtr); numEmps++ ) {
// I'm assuming emps is preallocated.
struct Employee emp = emps[numEmps-1];
sscanf(singleLine, "%80s %f %f",
emp.emps.name,
&emp.emps.rate,
&emp.emps.hours
);
}
Notice rather than using feof I'm looking at the return value of fgets. As Edward Karak mentioned, when reading lines don't check for eof.
Other issues in the code...
You're not checking whether your files actually opened.
fopen_s(&fPtr, fileName, "r");
if( !fPtr ) {
perror(fileName);
exit(1);
}
The code uses a lot of global variables. This leads to hard to understand code as anything can change those globals at any time. Instead, take advantage of function arguments and return values. Then you can completely understand a function just by looking at it.
For example, loadEmployee should take the struct to populate and the filename to read from, then return how many it read. saveEmployee is similar.
int loadEmployee(struct Employee *emps, char *fileName) {
...
return numEmps;
}
void saveEmployee(struct Employee *emps, char *fileName) {
...
}
Neither should be in charge of asking the user for the filename. This should be handled by the caller. Functions should do one thing; it makes them simpler and more flexible.
We can move the logic to get the filename into a function. Rather than using a global, we use a static variable. This variable is still local to the function, but does not get reset. getFileName remembers the filename.
char *getFileName() {
static char fileName[80] = "";
if (strcmp(fileName, "") == 0)
{
printf("\nWhat's the name of the file? ");
scanf("%20s", fileName);
}
return fileName;
}
...
switch(choice) {
case 1:
numEmps = loadEmployee(emps, getFileName());
break;
...
case 5:
printf("Quitting program!");
saveEmployee(emps, getFileName());
return;
}
...
These are not the source of your problem, but they will help structure your code so it's easier to understand and debug.
It's my first time asking here, so I'm sorry in advance if my post is a bit messy. I'm a freshman and my finals is to make an atm program.
My program uses switch statements for the options: the first one asks the user for their info, (account number, account name, PIN, initial deposit), while the second one is for the actual transactions: Balance check, Deposit and Withdrawal. Before you could do any one of those options, of course I'll have to check if the info (in this case the account number and PIN) matches the ones in my file.
The file is in binary. My problem is that my code for reading the file works fine if i want to display the contents of my file (all the data entries that I populated the file with are shown), but when i want to use the contents of the file (searching inside the file for a match of the user inputted account number) it only reads the first line of the file, thus only the first data entry works, while the one's after that are not read.
My question is, what am i doing wrong in my code? its confusing because if I change my code to display the contents it shows everything, meaning it reads the whole file. but when i want to search the file using a conditional statement, only the first data entry gets read. Thank you very much for your time
tldr: can't use data in file for conditionals (verify the data inside the file, cuz my code doesn't read it whole apparently, except for the first entry)
but if i print the contents it reads it fully
my outputs
1.My data entries
data entries
2.Entering the Account no. of the 1st one (desired output)
desired output
3.Entering The account no. of the 2nd one (Problem part)
problem
my main code
#include<stdio.h>
#include<conio.h>
#include<ctype.h>
#include<stdlib.h>
#include<string.h>
#include<process.h>
struct account
{
int no;
char name[100];
int pin;
float id;
};
main()
{
FILE *fptr;
fptr = fopen("accrec.dat","ab");
if (fptr == NULL)
{
printf("File does not exists \n");
return 0;
}
system("cls");
struct account accrec;
int i,tpin[4];
char step1,ch;
printf("\t\tWelcome to Banking System\n\t");
printf("\nA.Open an Account\n");
printf("\nB.Bank Transaction\n");
printf("\nC.exit\n");
scanf("%c",&step1);
switch (step1)
{
case 'A':
printf("Open a New Account\n");
printf("\nEnter the following information\n");
printf(" \n5-digit Account number:");
scanf("%d",&accrec.no);
getchar();
printf("\nAccount Name:");
scanf("%[^\n]s",&accrec.name);
printf("\n4-digit Account PIN:");
/*for(i=0;i<4;i++)
{
ch = getch();
tpin[4] = ch;
ch = '*' ;
printf("%c",ch);
}mask works but does not allow PIN saving */
scanf("%d",&accrec.pin);
printf("\nInitial deposit:");
scanf("%f",&accrec.id);
fwrite(&accrec,sizeof(struct account),1,fptr);
fclose(fptr);
break;
case 'B':
{
fptr = fopen("accrec.dat","rb");
int choice;
int accno = 0;
printf("Enter Your Account no.");
scanf("%d",&accno);
while (fread(&accrec,sizeof(account),1,fptr)!=NULL)
{
if(accno == accrec.no)
{
printf("\tWelcome to PUPQC Banking System\n");
printf("1.Balance Inquiry\n");
printf("2.Deposit\n");
printf("3.Withdrawal\n");
printf("4.quit\n");
scanf("%d",&choice);
}
else
{
printf("account doesn't exist\n");
exit(1);
}
fclose(fptr);
switch (choice)
{
case 1:
printf("BALANCE INQUIRY\n");
printf("Current Balance:");
fptr = fopen("accrec.dat","rb");
if (fptr == NULL)
{
printf("File Cant be read");
exit(1);
}
printf("Account No: %d\n",accrec.no);
while(fread(&accrec,sizeof(struct account),1,fptr)!=NULL);
{
printf("Initial Deposit is %0.2f\n",accrec.id);
}
printf("%d\n",&accrec.id);
break;
case 2:
float dv;
printf("DEPOSIT\n");
printf("Current Balance:");
fptr = fopen("accrec.dat","rb");
if (fptr == NULL)
{
printf("File Cant be read");
exit(1);
}
while(fread(&accrec,sizeof(struct account),1,fptr)!=NULL);
{
printf("%0.2f\n",accrec.id);
}
printf("Enter amount to deposit:\n");
printf("Deposit Value:");
scanf("%0.2f",&dv);
accrec.id = accrec.id + dv;
fwrite(&accrec,sizeof(struct account),1,fptr);
fclose(fptr);
break;
case 3:
float wv;
printf("WITHDRAWAL\n");
printf("Current Balance:");
fptr = fopen("accrec.dat","rb+");
if (fptr == NULL)
{
printf("File Cant be read");
exit(1);
}
while(fread(&accrec,sizeof(struct account),1,fptr)!=NULL);
{
printf("%0.2f\n",accrec.id);
}
printf("Enter amount to withdraw:\n");
printf("Withdrawal Value:");
scanf("%0.2f",wv);
accrec.id = accrec.id - wv;
fwrite(&accrec,sizeof(struct account),1,fptr);
fclose(fptr);
break;
case 4:
printf("thank you for your patronage \n");
return 0;
break;
default:
printf("error 404");
break;
}
}
}
break;
case 'C':
printf("Thank you! Have a good day");
return 0;
break;
case 'D':
fptr = fopen("accrec.dat","rb");
if (fptr == NULL)
{
printf("File Cant be read");
exit(1);
}
printf("Data From file\n");
while(fread(&accrec,sizeof(struct account),1,fptr)!=NULL)
printf("\n acc.no is %d\n acc.name is %s\n PIN %d\n Initial Deposit is %0.2f\n ",accrec.no,accrec.name,accrec.pin,accrec.id);
fclose(fptr);
getch();
break;
default:
printf("invalid input! please select form the options given\n");
}
}
my structure
struct account
{
int no;
char name[100];
int pin;
float id;
};
code for finding a match of account number in my file
(the part i'm having trouble with)
fptr = fopen("accrec.dat","rb");
int choice;
int accno = 0;
printf("Enter Your Account no.");
scanf("%d",&accno);
while (fread(&accrec,sizeof(account),1,fptr)!=NULL)
{
if (accno == accrec.no)
{
printf("\tWelcome to Banking System\n");
printf("1.Balance Inquiry\n");
printf("2.Deposit\n");
printf("3.Withdrawal\n");
printf("4.quit\n");
scanf("%d",&choice);
}
else
{
printf("account doesn't exist\n");
exit(1);
}
}
fclose(fptr);
The expected output is that my conditional statement works properly and reads my whole file for matches.
try to change the exit(1) to continue;, the exit(1) will make your program quit the while loop and exit the program immediately whenever accno != accrec.no.
in fact, you don't need the else statement inside the while loop, you should put it outside the while loop. for example:
scanf("%d",&accno);
boolean found = false;
while (fread(&accrec,sizeof(account),1,fptr)!=NULL)
{
if (accno == accrec.no)
{
found = true;
scanf("%d",&acpin);*/
printf("\tWelcome to Banking System\n");
printf("1.Balance Inquiry\n");
printf("2.Deposit\n");
printf("3.Withdrawal\n");
printf("4.quit\n");
scanf("%d",&choice);
}
}
if (!found) {
printf("account doesn't exist\n");
}
fclose(fptr);
I'm trying to figure out how to work out the selection for when the input information is not present in the text file, the user will be notified. For now when I run my code and input an item that's not in the text file, it just print out the last item in the text file. I'm really stuck after several hours of thinking how to solve this problem. Your help is greatly appreciated.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<conio.h>
#include<ctype.h>
int main()
{
FILE *items;
char pName[20];
float pPrice;
char p1Name[20];
int found=0, i=9;
char respond='y';
items=fopen("Product_Name_Price.txt", "r");
if(items==NULL)
{
fprintf(stderr, "Can't open file Product_Name_Price.txt!\n");
exit(1);
}
printf("File has been successfully opened\n");
while(tolower(respond) == 'y')
{
items=fopen("Product_Name_Price.txt", "r");
printf("Enter the name of the product you are looking for\n");
scanf("%s", p1Name);
while(!feof(items))
{
fscanf(items, "%s%f", pName, &pPrice);
i=strcmp(p1Name, pName);
if(i == 0)
{
found=1;
break;
}
else
{
found=0;
}
}
if(found=1)
{
printf("%s\t%.2f\n", pName, pPrice);
}
else
{
printf("No such product information in the database\n");
}
printf("Do you want to look for more item? (Y/N)\n");
scanf(" %c", &respond);
fclose(items);
}
}
if(found=1) should be if(found == 1)