I'm making some small changes to a preexisting application. The app is writing lines of text to a buffer and then flushing the buffer. I'm not sure when it actually writes the text to the file, but I'm trying to copy everything in that buffer and write a copy of it all out to a completely different file.
Below is the last line of writing to the preexisting buffer before it eventually calls fflush().
fprintf(_log, "-- FINAL TEXT LINE --\n");
Below is my code that I'm using in an attempt to copy that buffer to a separate file which is dynamically named according to the log time. This custom-%ld.log does not already exist and needs to be created.
char tmp[sizeof(_log)];
sprintf(tmp, "custom-%ld.log", (long int)lf->time);
FILE *fp1, *fp2;
char a;
fp1 = _log;
fp2 = fopen(tmp, "a");
if (fp2 != NULL) {
do {
a = fgetc(fp1);
fputc(a, fp2);
} while (a != EOF);
fflush(fp1);
fclose(fp2);
}
fflush(_log);
I'm sure my mistakes are very basic, but I don't know what I'm doing. I've tried dozens of suggestions on other websites, and suggestions here from other questions, but I'm not having any luck.
Yes, there are a few mistakes in here.
This will allocate a buffer of 4 or 8 bytes depending on the word size of your computer. 'sizeof' is a compile time directive that gives you the size of the underlying type.
char tmp[sizeof(_log)];
So do this instead (where 100 is just a big enough number to hold the result):
char tmp[100];
Next using a char for 'a' will not be able to hold the EOF value. Use int.
int a;
By fixing the definition of 'a' your loop is now not infinite, but it will eventually write the constant EOF to the file, which will be some garbled character. Change it like so:
while ((a = fgetc(fp1)) != EOF) {
fputc(a, fp2);
}
So in the end you should have:
char tmp[100];
sprintf(tmp, "custom-%ld.log", (long int)lf->time);
FILE *fp1, *fp2;
int a;
fp1 = _log;
fp2 = fopen(tmp, "a");
if (fp2 != NULL) {
while ((a = fgetc(fp1)) != EOF) {
fputc(a, fp2);
}
fflush(fp1);
fclose(fp2);
}
fflush(_log);
You are writing EOF to file before checking it with
do {
a = fgetc(fp1);
fputc(a, fp2);
} while (a != EOF);
You could try
int a; // make sure you have the correct type
while((a = fgetc(fp1)) != EOF)
fputc(a, fp2);
}
EOF is not (except some legacy formats) part of the file. It is an indicator returned by file reading functions.
Note that fflush(fp1); is undefined behaviour when fp1 is opened for input.
You say "custom-%ld.log" does not already exist yet you open it with
fp2 = fopen(tmp, "a");
Which would append, if you forgot to delete a previous version. To make sure it is a new file, open with
fp2 = fopen(tmp, "w");
Related
1, 2, 3 // a.txt
This program is for opening the file, counting the numbers and reading the first letter of txt file.
When I tried debugging, digit_char = fgetc(fp); doesn't worked properly. digit_char was empty. I used dynamic allocation to save the numbers in the array. There was no warning but the answer was not what I wanted. (digit_char=1)
FILE* fp;
char digit_char;
int NUM=1;
fp = fopen("a.txt", "r");
char ch;
do
{
ch = fgetc(fp);
if (ch == ',')
{
NUM++;
}
} while (ch != EOF);
int* arr;
arr = (int*)malloc(sizeof(int) * NUM);
digit_char = fgetc(fp); // error...?
free(arr);
fclose(fp);
======
The following code fgetc() works very well. 1is saved in digit_char
FILE* fp;
char digit_char;
int NUM=3;
fp = fopen("a.txt", "r");
int arr[3];
digit_char = fgetc(fp);
//free(arr);
fclose(fp);
return 0;
I don't know why the first program doesn't work well..
Once you have reached EOF, you're really at the end of the file. There's nothing more to read.
You need to rewind to the beginning of the file before attempting to read again.
Or at least seek to an earlier position.
Note that it's not possible to rewind or seek in the standard input stream stdin. To continue reading from stdin even after the user pressed the "end-of-file" button sequence, you need to clear the "error".
I need to write some code to read an equation from a text file and write the answer to a new one, and I'm completely stuck
I've managed to read the question and print it in terminal as characters, but that's it.
this new code can't even do that.
for those asking, the exact wording of the question is this:
"Read an input file: questions.txt; and produce a program that creates an output file answers.txt that includes
the question and the answer for each line in the questions file.
For example, if the line in questions is:
5*5
the answer file should read:
5*5 = 25
Allow for the following operations: +, -, *, /, % and for the correct order of operations. Also allow for at least 2
operators (3 operands), for example:
3+5*5 = 28"
My main problem is reading the equation from the text file and separating it into numbers and the operator symbol
FILE *fp;
int a, b, c, ch, i, number[100];
char input[5];
fp = fopen ("questions.txt", "r");
while(1)
{
ch = fgetc(fp);
if (ch == EOF)
{
break;
}
else
{
input[i] = ch;
}
}
fclose(fp);
printf("%s", input);
}
There are errors:
check file has been open correcly: if (fp != NULL)
i = 0; on begin, now we dont know value
input[i] = ch; => input[i++] = (char)ch;
if (ch == EOF) => if (ch == EOF && i < 4) 4 because 5 - 1 and move this to const or macro
After break of while input[i] = '\0';
You need to open the file you want to read from in read mode with the normal fopen('questions.txt', 'r') like you did. Next, you need to fopen('newFile.txt', 'w') you want to write to in w write mode. Use a while loop to get each character of the questions.txt file with getc(fileToRead) while you haven''t hit the end of the questions.txt file, hence ... != EOF, and write to the newFile.txt. The printf("%c", c) is to print each character as you read it from questions.txt.
FILE *fileToRead, *fileToWrite;
int c;
//open the questions.txt file in read mode
*fileToRead = fopen ("questions.txt", "r");
//create newFile.txt and open it in write mode
*fileToWrite = fopen ("newFile.txt", "w");
while ((c = getc(fileToRead)) != EOF) {
putc((char)c, fileToWrite );
printf("%c", (char)c);
}
fclose(fileToRead);
fclose(fileToWrite);
I'm new to C language and I'm trying to save data to a .csv and read the same data in a very simple program.
char c;
FILE *fp;
fp = fopen("file.csv", "w+");
fprintf(fp, "Hello;World\nLine");
fclose(fp);
fp = fopen("file.csv", "r");
while (getc(fp) != EOF) {
printf("%c", getc(fp));
}
fclose(fp);
I don't know why the output is wrong:
el;ol
ie
Thanks in advance
Because you are reading a character in the loop condition (so it prints out every other one when printing), and reading another one when printing it out. Try this:
int ch;
while ((ch=getc(fp)) != EOF) {
printf("%c", ch);
}
Here:
while (getc(fp) != EOF) {
printf("%c", getc(fp));
}
You are calling getc() twice every time through the loop, but only printing one character. So you get half te hrces rm te fl n ls h ohr hl.
I am having two inputs :video1.y and video2.y .I want to Concatenate these two files to create one video.y file ??I am writing code in C .It may be basic question but not able to do that !! Both inputs are having same hight and width .
Code:
int main()
{
// Open two files to be merged
FILE *fp1 = fopen("D:\\dump\\video1.y", "rb");
FILE *fp2 = fopen("D:\\dump\\video2.y", "rb");
// Open file to store the result
FILE *fp3 = fopen("D:\\dump\\video.y", "wb");
char c; //Change char to int as per answer given by user3710044..
//...Which is working !!
if (fp1 == NULL || fp2 == NULL || fp3 == NULL)
{
puts("Could not open files");
exit(0);
}
// Copy contents of first file to video3.y
while ((c = fgetc(fp1)) != EOF)
fputc(c, fp3);
// Copy contents of second file to video3.y
while ((c = fgetc(fp2)) != EOF)
fputc(c, fp3);
printf("Merged video1.y and video2.y into video.y");
fclose(fp1);
fclose(fp2);
fclose(fp3);
return 0;
}
video1.y and video2.y are of 55 MB .and my output is 3 KB.I am not able to concatenate this two inputs
The type of the c variable is a char this cannot hold the value for EOF and all 256 byte values.
As it happens on your machine char is a signed type so the cast return result from fgetc and the cast value of EOF actually mean that an EOF is found at the end of a file. The problem is that if the file contains an 0xFF byte this is also seen as an EOF.
In summary, change the type of c to an int.
I use below code to read a char from file and replace it with another,
but I have an error.loop in going to end of file.
What is wrong?
I tested this code on linux (netbeans IDE) and it was correct and worked beautiful but when I tried to use VS 2008 in windows , I found a non end loop.
//address = test.txt
FILE *fp;
fp=fopen(address,"r+");
if(fp == 0)
{
printf("can not find!!");
}
else
{
char w = '0'; /// EDIT : int w;
while(1)
{
if((w = fgetc(fp)) != EOF)
{
if((w = fgetc(fp)) != EOF)
{
fseek(fp,-2,SEEK_CUR);
fprintf(fp,"0");
}
}
else
{
break;
}
}
}
fclose(fp);
You are storing the result of fgetc in a char, instead of an int.
char w = '0'; /* Wrong, should be int. */
Incidentally, this problem is mentioned in the C FAQ.
If type char is unsigned, an actual
EOF value will be truncated (by having
its higher-order bits discarded,
probably resulting in 255 or 0xff) and
will not be recognized as EOF,
resulting in effectively infinite
input.
EDIT
Reading your question again, it's highly fishy the way you seek back two characters and write one character. That could well lead to an infinite loop.
EDIT2
You (likely) want something like this (untested):
while ((w = getc(fp)) != EOF) {
fseek(fp, -1, SEEK_CUR);
fprintf(fp, "0");
fflush(fp); /* Apparently necessary, see the answer of David Grayson. */
}
The fopen documentation on cplusplus.com says:
For the modes where both read and
writing (or appending) are allowed
(those which include a "+" sign), the
stream should be flushed (fflush) or
repositioned (fseek, fsetpos, rewind)
between either a reading operation
followed by a writing operation or a
writing operation followed by a
reading operation.
We can add an fflush call after the fprintf to satisfy that requirement.
Here is my working code. It creates a file named example.txt and after the program exits that file's contents will be 000000000000n.
#include <stdio.h>
int main(int argc, char **argv)
{
FILE * fp;
int w;
fp = fopen("example.txt","w");
fprintf(fp, "David Grayson");
fclose(fp);
fp = fopen("example.txt","r+");
while(1)
{
if((w = fgetc(fp)) != EOF)
{
if((w = fgetc(fp)) != EOF)
{
fseek(fp,-2,SEEK_CUR);
fprintf(fp,"0");
fflush(fp); // Necessary!
}
}
else
{
break;
}
}
fclose(fp);
}
This was tested with MinGW in Windows.