Merging text from two text files alternatively - c

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

Related

Merging text alternatively line by line from two files

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();
}

I can't get my code to break out of the switch statement

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 {...}

Segmentation Fault occurred when using function inside a switch/ifelse statement in a c language

I'm new to c programming. I'd like to use a function inside a switch or if else statement. But after I run the program. It immediately show me segmentation fault and exit the program. Below is my code. Please run through it
void phone1();
int main()
{
int option;
while (1) {
printf("1) Option 1 \n");
printf("2) Option 2 \n");
scanf("%d", &option);
switch (option) {
case 1:
phone1();
break;
case2:
phone2();
break;
default:
printf("Error");
break;
}
while (1);
return 0;
}
}
void phone1()
{
FILE* fi;
char value[100];
fi = fopen("phone.txt", "r");
fseek(fi, -10, SEEK_END);
fgets(value, 100, fi);
printf("%s", value);
fclose(fi);
}
And here is my phone.txt file
phone1 John 192901
phone2 Joseph 858201
phone3 Jay 757279
phone4 Teddy 847291
phone5 Ed 469274
I tried the function outside switch statement inside int main() and everything works fine. So I don't know what cause the segmentation fault to fail within the switch statement.
First of all, you need to add a closing brace for the while loop block and to omit the one in the end.
Second, you shouldn't fseek() to a negative. What did you try to achieve?
Your function opens a file, and reads the first 100 characters into value. Then, it prints them. I think i get what you are trying to achieve here, so this is an example of roughly how I'd do it.
#include <stdio.h>
int main()
{
FILE *fptr = fopen("contacts.txt", "r");
int contact;
char name[100]; // or whatever size you need
int number;
char c = 'a';
scanf("%d", &contact);
++contact; // to use 1-based numbering
for (int i = 0; i < contact && c != EOF; ++i)
while ((c = fgetc(fptr)) != EOF && c != '\n');
// safely jumps to contact-th line
fscanf(fptr, "%s %d", name, &number);
printf("%s\t%d\n", name, number);
return 0;
}
Which would need a contacts.txt in the form:
Ed 1234
Emma 7890
You could also make it check how many contact entries/lines are there, and bound-check the input.

If a word has been found then how to replace it in another file?

I have this code which I divided in two parts just for understanding purpose. The first option is working fine and showing me details to update.
I have a problem with the second part in which a code is taking name/word from the file correctly but I don't know how to replace it with the new name/word in another file? Could you help me with some code because I searched a lot? Thanks!
Here is file.txt
bilalkhan 20/20/1980 908732343
Here is a code
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
void firstWord(char str[]){
int i = 0;
while(!isspace(str[i])){
i++;
}
str[i]='\0';
}
void hello(){
int option;
char updated_name[50], read[100];
short int FLAG = 0;
static const char * listing[] = {"Name", "Date of birth","ID card number"};
FILE * fr3 = fopen("file.txt","r");
FILE * fw1 = fopen("new.txt","w");
if (fr3 == NULL || fw1 == NULL) {
perror("Unable to read text file.");
exit(0);
}
for (option = 1; option <= sizeof(listing)/sizeof(char *); ++option)
printf("%d. Your %s\n", option, listing[option-1]);
SELECT OPTION TO UPDATE
fputs("Select your choice to update: ", stdout);
scanf("%d", &option);
char string[100];
if (option == 1){
while(fgets(string, 100, fr3) != NULL){
firstWord(string);
printf("'%s' found. Now replace it with another name: ", string);
scanf("%s", &updated_name);
// Here I want to update the name but don't know the code.
fclose(fr3);
exit(0);
}
}
fclose(fw1);
}
int main(){ hello(); }
Just write the updated name to the output file.
if (option == 1){
while(fgets(string, 100, fr3) != NULL){
firstWord(string);
printf("'%s' found. Now replace it with another name: ", string);
scanf("%s", &updated_name);
fprintf(fw1, "%s\n", updated_name);
fclose(fr3);
fclose(fw1);
exit(0);
}
}
fclose(fw1);
You're not really replacing anything, you're just asking for a new name and putting it into the file. The old name is not used in this process.

saving array to a file won't work, program crashes

I posted a few days ago already about a problem with my array-program. Well, it is basically a program which lets the user generate an array, safe a specific number in a specific slot, read the array or read a specific slots value. Now I am figuring out, how to let the user save the current array as a file.
this is what I got
void safeFile(){
FILE *f = fopen("list.txt", "a+");
putc(f , list);
fclose(f);
printf("File saved");
start();
}
where's the problem?
My Program crashes everytime I call the function safeFile() .
I played around, came with fputs instead of putc, program won't crash anymore, the file gets created but it's still blank
void safeFile(){
FILE *f = fopen("list.txt", "r+");
fputs(f , list);
fclose(f);
printf("File saved");
start();
}
here is my current full code
would be grateful for advices, im a newb
#include <stdio.h>
#include <stdlib.h>
int list[30];
int x = 0;
int i = 0; // variable used by for-Loop in setList
int j = 0; // variable used by for-Loop in getList
int input;
int option; //start Value
int gvinput; //getValue input
void start();
void getList();
int main()
{
start();
return 0;
}
void setList(int sizeOfList)
{
for (i = x; i <= sizeOfList; i++)
{
list[i] = i;
}
}
void getList(){
for(j = x; j < i ; j++ )
{
printf("At %d we got the value %d \n",j,list[j]);
}
}
void startList()
{
fflush(stdin);
printf("Please enter number between 0 and 30\n ");
scanf("%d",&input);
if(input > 30 || input == 0)
{
printf("The Number is not between 0 and 30\n");
startList();
}
setList(input);
getList();
fflush(stdin);
start();
}
void setValues(int l[])
{
fflush(stdin);
int v;
int loc;
printf("please enter what value you want to safe\n");
scanf("%d",&v);
fflush(stdin);
printf("Where do you want to save it?\n");
scanf("%d",&loc);
l[loc] = v;
printf("we got at slot %d the value %d\n\n",loc,l[loc]);
start();
}
void getValues(int getArray[]){
fflush(stdin);
printf("which slot do you want to read?\n");
scanf("%d",&gvinput);
fflush(stdin);
printf("The value is: %d \n\n",getArray[gvinput]);
start();
}
void safeFile(){
FILE *f = fopen("list.txt", "r+");
fputs(f , list);
fclose(f);
printf("File saved");
start();
}
void start(){
fflush(stdin);
printf("\n");
printf("[L] = generate Slots\n");
printf("[S] = set a Value at specific slot\n");
printf("[G] = get a Value from a specific slot\n");
printf("[F] = safe File");
printf("[X] = exit\n");
option=getchar();
if(option == 'L' || option == 'l'){
startList();
}
if(option == 'S' ||option == 's'){
setValues(list);
}
if (option =='G' ||option == 'g'){
getValues(list);
}
if (option == 'X' || option == 'x'){
printf("Thank you");
}
if (option == 'f' || option == 'F'){
safeFile();
}
int putc( int ch, std::FILE* stream );
putc writes a single char, and you pass an array of ints to it. The same is true for fputs, which writes a null-terminated string. You'll really have to write some code that serializes your data structure to a sequence of bytes to be written to the file.
In your case, since you want to save a list of ints, you can do this with a loop, for example, that is, loop over your array and write each item to the file. You'll also need a function that writes an int (putc isn't good here, since it writes a char). Have a look at printf, if you'd like to stick with C-style IO, otherwise use streams.
If your using putc(), you should be passing char by char.
for(i=0;i<strlen(list);i++)
{
putc(f,list[i]);
}
The list is an array, if you pass the address it means whole array so putc won't work here.
int fputs(const char *s, FILE *stream);
The second argument to the fputs is the stream. Since u use int [10]. u can use fprintf to print to the file.
Also, fflush(stdin); is undefined behaviour
you need to use the loop, but it is not working because the parameters in the putc function are not in the correct order. Try this:
for(i=0;i<strlen(list);i++)
{
putc(list[i],f); //<---------- NOT putc(f,list[i]);
}
first the char and second the stream.
int putc ( int character, FILE * stream );

Resources