int main()
{
char ch;
int word_count = 0, in_word = 0;
char file_name[MAX_LEN];
/* Pointer for both the file*/
FILE *fpr, *fpw;
/* Opening file INPUT.txt in “r” mode for reading */
start:
printf("Enter a file name: ");
scanf("%s", file_name);
fpr = fopen(file_name, "r");
/* Ensure INPUT.txt opened successfully*/
if (fpr == NULL)
{
system("cls");
printf("Could not open the file %s\n", file_name);
goto start;
}
while ((ch = fgetc(fpr)) != EOF) {
{
printf("%c",ch);
}
if(ch == ' ' || ch == '\t' || ch == '\0' || ch == '\n') {
if (in_word) {
in_word = 0;
word_count++;
}
} else {
in_word = 1;
}
}
printf("In the file %s:\n", file_name);
printf("Number of words: %d.\n", word_count);
/* Opening file OUTPUT.txt in “w” mode for writing*/
fpw= fopen("OUTPUT.txt", "w");
/* Ensure OUTPUT.txt opened successfully*/
if (fpw == NULL)
{
puts("Output file cannot be opened");
}
/*Read & Write Logic*/
while ((ch = fgetc(fpr)) != EOF)
{
fputc(ch, fpw);
}
/* Closing both the files */
fclose(fpr);
fclose(fpw);
return 0;
}
Why is it not printing in the output.txt file? And how can I also print the words in the output file?
There must be a conflict between the while function before printing the input. Or maybe there is something reading before the output then having conflict with another one, when I remove the while function (count words) it shows the product in the output.
You read from fpr until you reach EOF, then try to read from it again.
You need to rewind the file to the beginning for the second fgetc() loop to produce anything.
Related
I've been trying to merge the contents of two .txt files into a third .txt file that combines the output. All I know how to do (and all I have been able to find answers for), however, is to merge them by putting the contents of the first file first, and the second file second. However, I would prefer the output to list the first line of the first file, then the first line of the second file -- followed on a new line by the second line of the first file and the second line of the second file.
To make this clearer visually, the code is currently appearing as:
file1-line1
file1-line2
file1-line3
file2-line1
file2-line2
file2-line3
... When I'd like it to appear as:
file1-line1 file2-line1
file1-line2 file2-line2
file1-line3 file2-line3
The code I have is very basic and executes the first example fine:
int main()
{
FILE *pointer1 = fopen("file1.txt", "r");
FILE *pointer2 = fopen("file2.txt", "r");
FILE *pointer3 = fopen("combined.txt", "w");
int ch;
if (pointer1 == NULL || pointer2 == NULL || pointer3 == NULL)
{
puts("Could not open files");
exit(0);
}
while ((ch = fgetc(pointer1)) != EOF)
fputc(ch, pointer3);
while ((ch = fgetc(pointer2)) != EOF)
fputc(ch, pointer3);
printf("Merged file1.txt and file2.txt into combined.txt");
fclose(pointer1);
fclose(pointer2);
fclose(pointer3);
return 0;
}
Is there a way to output the described situation? I am aware that E0F refers to the end of a file, and is likely causing an issue. Is there a similar condition for an end of a line (like E0L)?
Edit: Changed char ch to int ch.
First, if you have a Unix-like system, the paste command already does that. Next as you want to process lines, you should use fgets. Here you have to loop over input files one line at a time, copy the lines to the output file without the newline, and add the new line after copying everything.
As the processing for both input files is the same, and as I am lazy, I wrote a function to only write it once. In the end code could be:
FILE *copyline(FILE *in, FILE *out) {
char line[256];
if (in != NULL) {
for (;;) { // loop if the line is larger that sizeof(line)
if (NULL == fgets(line, sizeof(line), in)) { // EOF on file1
fclose(in);
in = NULL;
break;
}
size_t end = strcspn(line, "\n");
if (end != 0) fwrite(line, 1, end, out); // smth to write
if (end != strlen(line)) break; // \n found: exit loop
}
}
return in;
}
int main()
{
FILE *pointer1 = fopen("file1.txt", "r");
FILE *pointer2 = fopen("file2.txt", "r");
FILE *pointer3 = fopen("combined.txt", "w");
const char sep[] = " "; // a separator between lines of both file
if (pointer1 == NULL || pointer2 == NULL || pointer3 == NULL)
{
puts("Could not open files");
exit(0);
}
for (;;) {
pointer1 = copyline(pointer1, pointer3);
fwrite(sep, strlen(sep), 1, pointer3);
pointer2 = copyline(pointer2, pointer3);
if (pointer1 == NULL && pointer2 == NULL) break;
fputc('\n', pointer3); // if smth was written, add a newline
printf(".");
}
printf("Merged file1.txt and file2.txt into combined.txt");
fclose(pointer3);
return 0;
}
Here's one way to approach it:
#include <err.h>
#include <libgen.h>
#include <stdio.h>
#include <stdlib.h>
FILE *
xfopen(const char *path, const char *mode)
{
FILE *fp = path[0] != '-' || path[1] != '\0' ? fopen(path, mode) :
*mode == 'r' ? stdin : stdout;
if( fp == NULL ) {
perror(path);
exit(EXIT_FAILURE);
}
return fp;
}
int
main(int argc, char **argv)
{
if( argc < 3 ) {
printf("usage: %s file1 file2\n", basename(argv[0]));
}
FILE *pointer1 = xfopen(argv[1], "r");
FILE *pointer2 = xfopen(argv[2], "r");
FILE *current = pointer1;
int ch;
while( ( ch = fgetc(current)) != EOF ) {
if( ch == '\n' ) {
if( current == pointer1 ) {
int k;
current = pointer2;
if( (k = fgetc(current)) != EOF ) {
ungetc(k, current);
ch = ' ';
}
} else {
current = pointer1;
}
}
putchar(ch);
}
if( ferror(current) ) {
err(EXIT_FAILURE, "Error reading %s",
current == pointer1 ? argv[1] : argv[2]);
}
current = current == pointer1 ? pointer2 : pointer1;
while( (ch = fgetc(current)) != EOF) {
putchar(ch);
}
fclose(pointer1);
fclose(pointer2);
return 0;
}
#include <stdio.h>
int main()
{
FILE *pointer1 = fopen("file1.txt", "r");
FILE *pointer2 = fopen("file2.txt", "r");
FILE *pointer3 = fopen("combined.txt", "w");
char ch1, ch2;
if (pointer1 == NULL || pointer2 == NULL || pointer3 == NULL)
{
puts("Could not open files");
return 0;
}
do
{
char c1 = fgetc(pointer1);
char c2 = fgetc(pointer2);
if (feof(pointer1) || feof(pointer2))
break;
while(c1!='\n')
{
fputc(c1,pointer3);
c1=fgetc(pointer1);
if(feof(pointer1)) break;
}
fputc(' ',pointer3);
while(c2!='\n')
{
fputc(c2,pointer3);
c2=fgetc(pointer2);
if(feof(pointer2)) break;
}
fputc('\n',pointer3);
} while (1);
printf("Merged file1.txt and file2.txt into combined.txt");
fclose(pointer1);
fclose(pointer2);
fclose(pointer3);
return 0;
}
This works like you want.
Output: Combined file.txt
file1-line1 file2-line1
file1-line2 file2-line2
file1-line3 file2-line3
I've got the following program, but there is a problem. First the program part that does not work:
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fp;
FILE *fp2;
char ch;
char fnamer[100];
char fnamer2[100]; //Storing File Path/Name of Image to Display
printf("\n\nPlease Enter the Full Path of the Image file you want to view: \n");
scanf("%s",&fnamer);
fp=fopen(fnamer,"r");
if(fp==NULL)
{
printf("Error!");
exit(1);
}
printf("\n\nPlease Enter the Full Path of the Image file you want to write to: \n");
scanf("%s",&fnamer2);
fp2=fopen(fnamer2,"w");
if(fp2==NULL)
{
printf("Error!");
exit(1);
}
else
{
// printf("test\n");
}
int line_number = 0;
int charsOnLine = 0;
fprintf(fp2, "%d: ", ++line_number); /* put line number in output file */
printf("%d: ", line_number);
while((ch = fgetc(fp)) != EOF )
{
//printf("test2");
fputc(ch,fp2);
printf("%c", ch);
if ( ch != '\n' && charsOnLine ==0 )
{
fprintf(fp2, "%d:", ++line_number ); /* put line number in output file */
printf("%d: ", line_number);
}
// if (ch != '\n' && charsOnLine 0 ){
// fprintf(fp2, "%c", ch);
// printf("%d", ch);
// }
}
fclose;
fclose(fp);
// fclose(fp2);
// getch();
}
The program needs to count the lines, give them a number but skip the blank lines. But here is the problem: when I run this code it gives all the chars a number.
You could use a flag to remember when you have just started a new line. The first time you see a char not equal to '\n', you print the line number and clear the flag.
Something like:
int line_number = 0;
int newLine = 1;
while((ch = fgetc(fp)) != EOF )
{
if (ch == '\n')
{
newLine = 1;
}
else
{
if (newLine)
{
fprintf(fp2, "%d:", ++line_number );
printf("%d: ", line_number);
newLine = 0;
}
}
fputc(ch,fp2);
printf("%c", ch);
}
From what I understand, the program needs to count the lines and append their content.
Then I would search for '\n' char, rather than skipping it with if (ch != '\n')
int main()
{
FILE *fp;
FILE *fp2;
char ch;
char fnamer[100];
char fnamer2[100]; //Storing File Path/Name of Image to Display
printf("\n\nPlease Enter the Full Path of the Image file you want to view: \n");
scanf("%s",&fnamer);
fp=fopen(fnamer,"r");
if(fp==NULL)
{
printf("Error!");
exit(1);
}
printf("\n\nPlease Enter the Full Path of the Image file you want to write to: \n");
scanf("%s",&fnamer2);
fp2=fopen(fnamer2,"w");
if(fp2==NULL)
{
printf("Error!");
exit(1);
}
int line_number = 0;
fprintf(fp2, "%d: ", ++line_number );
while((ch = fgetc(fp)) != EOF )
{
if ( ch == '\n' )
{
fprintf(fp2, "%d: ", ++line_number ); /* put line number in output file */
}
else {
fputc(ch,fp2); /* put the char in the corresponding line */
}
}
fclose(fp);
fclose(fp2);
}
I'm having some trouble with parsing a temp.txt folder which contains the basenames of various files in a directory. I'd like to sort through this file, figure out what each of the file types are line by line, and then delete them from the temp file. I have been able to do carry out the parsing of the file names to discover their type, but when I call my delete function... it only works for some of the files and leaves behind some junk occasionally.
The input file looks like this:
temp.txt input
The output file after running looks like this:
temp.txt output
#include < stdio.h >
#include < string.h >
#include < unistd.h >
#include < stdlib.h >
/* This program module parses through the temp.txt file and finds .gif, .png, and .bmp files
and prints to standard output their file type in the order in which they're found.
It also takes all the files that aren't of those three types and puts them in a junk file.
*/
int deleteline(int delete_line);
int main(int argc, char * argv[]) {
FILE * file = fopen("temp.txt", "r"); /* should check the result */
FILE * myfile = fopen("junkfiles.txt", "w");
char line[4069];
char * gif = ".gif";
char * png = ".png";
char * bmp = ".bmp";
int i = 0;
int j = 0;
// if tempfile cannot be created, error handle
if (!file) {
puts("Some kind of file error!");
return 1;
}
// if junkfile cannot be created, error handle
if (!myfile) {
puts("Some kind of file error!");
return 1;
}
while (fgets(line, sizeof(line), file)) {
i++;
if (strstr(line, gif) != NULL) {
j = deleteline(i);
fflush(NULL);
if (j == 0) {
printf("File on line %d is: ", i);
puts(line);
printf("This is a .gif\n\n");
} else {
printf("Some error on line %d\n", i);
}
} else if (strstr(line, png) != NULL) {
j = deleteline(i);
if (j == 0) {
printf("File on line %d is: ", i);
puts(line);
printf("This is a .png\n\n");
} else {
printf("Some error on line %d\n", i);
}
} else if (strstr(line, bmp) != NULL) {
j = deleteline(i);
if (j == 0) {
printf("File on line %d is: ", i);
puts(line);
printf("This is a .bmp\n\n");
} else {
printf("Some error on line %d\n", i);
}
} else {
j = deleteline(i);
if (j == 0) {
printf("The file on line %d is junk.\n\n", i);
} else {
printf("Some error on line %d\n\n", i);
}
fprintf(myfile, "%s", line);
}
}
/* may check feof here to make a difference between eof and io failure -- network
timeout for instance */
fclose(file);
fclose(myfile);
fflush(NULL);
return 0;
}
int deleteline(int delete_line) {
FILE * fileptr1, * fileptr2;
char * filename = "temp.txt";
char ch;
int temp = 1;
//open file in read mode
fileptr1 = fopen(filename, "r");
ch = getc(fileptr1);
//rewind
rewind(fileptr1);
//open new file in write mode
fileptr2 = fopen("replica.txt", "w");
while (ch != EOF) {
ch = getc(fileptr1);
if (ch == '\n')
temp++;
//except the line to be deleted
if (temp != delete_line) {
//copy all lines in file replica.c
putc(ch, fileptr2);
}
}
fclose(fileptr1);
fclose(fileptr2);
remove(filename);
//rename the file replica.c to original name
rename("replica.txt", filename);
return 0;
}
I have created a stock inventory program for a jewelry store.
However, I cannot seem to figure out how to search for a specific word in a file containing the items (in a table form) and delete the entire line which the word was on.
For example, I can delete earring from the list but not the quantity as well which would be a few spaces away on the same line.
#include <stdio.h>
int main() {
FILE *fp1, *fp2;
//consider 40 character string to store filename
char filename[40];
char c;
int del_line, temp = 1;
//asks user for file name
printf("Enter file name: ");
//receives file name from user and stores in 'filename'
scanf("%s", filename);
//open file in read mode
fp1 = fopen(filename, "r");
c = getc(fp1);
//until the last character of file is obtained
while (c != EOF) {
printf("%c", c);
//print current character and read next character
c = getc(fp1);
}
//rewind
rewind(fp1);
printf(" \n Enter line number of the line to be deleted:");
//accept number from user.
scanf("%d", &del_line);
//open new file in write mode
fp2 = fopen("copy.c", "w");
c = getc(fp1);
while (c != EOF) {
c = getc(fp1);
if (c == '\n')
temp++;
//except the line to be deleted
if (temp != del_line) {
//copy all lines in file copy.c
putc(c, fp2);
}
}
//close both the files.
fclose(fp1);
fclose(fp2);
//remove original file
remove(filename);
//rename the file copy.c to original name
rename("copy.c", filename);
printf("\n The contents of file after being modified are as follows:\n");
fp1 = fopen(filename, "r");
c = getc(fp1);
while (c != EOF) {
printf("%c", c);
c = getc(fp1);
}
fclose(fp1);
return 0;
}
Your code has several issues:
You read the filename with an unprotected call to scanf, if the name typed by the user exceeds 39 characters, you invoke undefined behavior. Make the buffer larger as filenames tend to be long nowadays and protect the format this way:
char filename[256];
if (scanf("%255s", filename) != 1) {
/* end of file reached, deal with this error */
...
}
Your method for reading a file byte by byte is incorrect: c should be defined as an int otherwise you cannot reliably detect EOF. The standard idiom for this is:
int c;
//until the last character of file is obtained
while ((c = getc(fp1)) != EOF) {
//print current character and read next character
putchar(c);
}
In the copy phase, you drop the first character of the file.
You ignore errors. Not only do you invoke undefined behavior, you may actually erase the file after failing to copy its contents.
You ask for a line number from the user, but you do not show the line numbers in the echo phase. Doing so would help.
Here is a improved version:
#include <stdio.h>
int main(void) {
FILE *fp1, *fp2;
//consider 255 character string to store filename
char filename[256];
int c, last, del_line, lineno;
//asks user for file name
printf("Enter file name: ");
//receives file name from user and stores in 'filename'
if (scanf("%255s", filename) != 1) {
perror("missing filename");
return 1;
}
//open file in read mode
fp1 = fopen(filename, "r");
if (fp1 == NULL) {
perror("cannot open file");
return 1;
}
//until the last character of file is obtained
last = '\n';
lineno = 0;
while ((c = getc(fp1)) != EOF) {
if (last == '\n') {
printf("%4d: ", ++lineno);
}
//print current character and read next character
putchar(c);
last = c;
}
rewind(fp1);
printf("\nEnter line number of the line to be deleted: ");
//accept number from user.
if (scanf("%d", &del_line) != 1) {
perror("missing line number");
return 1;
}
if (del_line < 1 || del_line > lineno) {
printf("no such line: %d\n", del_line);
return 1;
}
//open new file in write mode
fp2 = fopen("copy.c", "w");
if (fp2 == NULL) {
perror("cannot open copy.c");
return 1;
}
lineno = 1;
while ((c = getc(fp1)) != EOF) {
//except the line to be deleted
if (lineno != del_line) {
//copy all lines in file copy.c
putc(c, fp2);
}
if (c == '\n')
lineno++;
}
//close both files.
fclose(fp1);
if (fclose(fp2)) {
perror("write error to copy.c");
return 1;
}
// remove original file (unsafe)
// uncomment this if your system does not allow rename
// to overwrite existing files
// if (remove(filename)) {
// perror("cannot remove source file");
// return 1;
// }
//rename the file copy.c to original name
if (rename("copy.c", filename)) {
perror("cannot rename file");
return 1;
}
printf("\nThe contents of file after being modified are as follows:\n");
fp1 = fopen(filename, "r");
if (fp1 == NULL) {
perror("cannot re-open modified file");
return 1;
}
while ((c = getc(fp1)) != EOF) {
putchar(c);
}
fclose(fp1);
return 0;
}
I want to write code were the user is asked to write the name of a file. Then I want to analyze the file's content for a symbol, let's say 'e'.
My problem is that I don't know how to start analyzing the file the correct way so that the content can be checked.
int main() {
char c[1000], file_name[1000];
int i;
int s = 0;
FILE *fp;
printf("Enter the name of file you wish to see\n");
gets(file_name);
if ((fp = fopen(file_name, "r")) == NULL){
printf("Error! opening file");
exit(1);
}
if (fp) {
while (fscanf(fp, "%s", c) != EOF) {
printf("%s", c);
}
fclose(fp);
for (i = 0; c[i] != '\0'; ++i) {
puts(c);
if (c[i] == 'e') {
++s;
}
}
printf("\nWhite spaces: %d", s);
_getche();
return 0;
}
}
char line[512]; /*To fetch a line from file maximum of 512 char*/
rewind(fp);
memset(line,0,sizeof(line)); /*Initialize to NULL*/
while ( fgets(line, 512, fp ) && fp !=EOF)
{
/*Suppose u want to analyze string "WELL_DONE" in this fetched line.*/
if(strstr(line,"WELL_DONE")!=NULL)
{
printf("\nFOUND KEYWOD!!\n");
}
memset(line,0,sizeof(line)); /*Initialize to null to fetch again*/
}
If its just a symbol you're looking for, or a char, you can simply use getc() :
int c;
....
if (fp) {
while ((c = getc(fp)) != EOF) {
if (c == 'e') {
// Do what you need
}
}
Or, alternatively, if it's a word you're looking for, fscanf() will do the job:
int c;
char symb[100];
char symbToFind[] = "watever"; // This is the word you're looking for
....
while ((c = fscanf(fp, %s, symb)) != EOF) {
if (strcmp(symb, symbToFind) == 0) { // strcmp will compare every word in the file
// do whatever // to symbToFind
}
}
These alternatives will allow you to search every char or string in the file, without having to save them as an array.