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.
Related
there is very long "dict.txt" file.
the size of this file is about 2400273(calculated by fseek, SEEK_END)
this file has lots of char like this 'apple = 사과'(simillar to dictionary)
Main problem is that reading file takes very long time
I couldn't find any solution to solve this problem in GOOGLE
The reason i guessed is associated with using fgets() but i don't know exactly.
please help me
here is my code written by C
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
int line = 0;
char txt_str[50];
FILE* pFile;
pFile = fopen("dict_test.txt", "r");
if (pFile == NULL) {
printf("file doesn't exist or there is problem to open your file\n");
}
else {
do{
fgets(txt_str, 50, pFile);;
line++;
} while (txt_str != EOF);
}
printf("%d", line);
}
Output
couldn't see result because program was continuosly running
Expected
the number of lines of this txt file
Major
OP's code fail to test the return value of fgets(). Code needs to check the return value of fgets() to know when to stop. #A4L
do{
fgets(txt_str, 50, pFile);; // fgets() return value not used.
Other
Line count should not get incremented when fgets() returns NULL.
Line count should not get incremented when fgets() read a partial line. (I. e.) the line was 50 or longer. Reasonable to use a wider than 50 buffer.
Line count may exceed INT_MAX. There is always some upper bound, yet trivial to use a wider type.
Good practice to close the stream.
Another approach to count lines would use fread() to read chunks of memory and then look for start of lines. (Not shown)
Recommend to print a '\n' after the line count.
int main(void) {
FILE* pFile = fopen("dict_test.txt", "r");
if (pFile == NULL) {
printf("File doesn't exist or there is problem to open your file.\n");
return EXIT_FAILURE;
}
unsigned long long line = 0;
char txt_str[4096];
while (fgets(txt_str, sizeof txt_str, pFile)) {
if (strlen(txt_str) == sizeof txt_str - 1) { // Buffer full?
if (txt_str[sizeof txt_str - 1] != '\n') { // Last not \n?
continue;
}
}
line++;
}
fclose(pFile);
printf("%llu\n", line);
}
fgets returns NULL on EOF.
You are never assigning the result of
fgets(txt_str, 50, pFile);
to txt_str, your program never sees the end of the file and thus enters an endless loop.
try something like this:
char* p_str;
do{
p_str = fgets(txt_str, 50, pFile);
} while (p_str != NULL);
I have a list of columns containing text but I just to fetch first upper row from this list. How to do that?
#include <stdio.h>
int main()
{
FILE *fr;
char c;
fr = fopen("prog.txt", "r");
while( c != EOF)
{
c = fgetc(fr); /* read from file*/
printf("%c",c); /* display on screen*/
}
fclose(fr);
return 0;
}
Your stop condition is EOF, everything will be read to the end of the file, what you need is to read till newline character is found, furthermore EOF (-1) should be compared with int type.
You'll need something like:
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fr;
int c;
if(!(fr = fopen("prog.txt", "r"))){ //check file opening
perror("File error");
return EXIT_FAILURE;
}
while ((c = fgetc(fr)) != EOF && c != '\n')
{
printf("%c",c); /* display on screen*/
}
fclose(fr);
return EXIT_SUCCESS;
}
This is respecting your code reading the line char by char, you also have the library functions that allow you to read whole line, like fgets() for a portable piece of code, or getline() if you are not on Windows, alternatively download a portable version, and, of course you can make your own like this one or this one.
For whatever it's worth, here's an example that uses getline
#include <stdio.h>
int main()
{
FILE *fr;
char *line = NULL;
size_t len = 0;
ssize_t nread;
if (!(fr = fopen("prog.txt", "r"))) {
perror("Unable to open file");
return 1;
}
nread = getline(&line, &len, fr);
printf("line: %s, nread: %ld\n", line, nread);
fclose(fr);
return 0;
}
Some notes:
getline() can automatically allocate your read buffer, if you wish.
getline() returns the end of line delimiter. You can always strip it off, if you don't want it.
It's ALWAYS a good idea to check the status of I/O calls like "fopen()".
just replace EOF as '\n'(new line char). Than your code will read until reaching the new line. Here is what it looks like:
#include <stdio.h>
int main()
{
FILE *fr;
char c = ' ';
fr = fopen("prog.txt", "r");
while(c != EOF && c != '\n')
{
c = fgetc(fr); /* read from file*/
if(c != EOF){
printf("%c",c); /* display on screen*/
}
}
fclose(fr);
return 0;
}
I have not tested it yet but probably work. Please let me know if there is some problem with the code i will edit it.
Edit1:char c; in line 5 is initialized as ' ' for dealing with UB.
Edit2:adding condition (c != EOF) to while loop in line 7, for not giving reason to infinite loop.
Edit3:adding if statement to line 10 for not printing EOF which can be reason for odd results.
So, I'm just learning how to code in C and I'm a bit stumped by what my teacher is asking. Basically, we need to create a program that reads characters from two separate files character by character and if the two characters are the exact same it is to be printed to a third file. Normally, I would use an array to do this but, we have specifically been told that we are not allowed to use an array. I sort of have it working in that it prints characters to the third file but it prints numbers and punctuation in addition to characters. Obviously, I'm missing something but I don't know what it is. Here is my code:
int main(int argc, char *argv[]) {
FILE *fp, *fp2, *ofp;
char a, b;
fp = fopen("input1a.txt", "r");
fp2 = fopen("input1b.txt", "r");
ofp = fopen("output.txt", "w");
while((a=getc(fp))!= -1){
b=getc(fp2);
if(isalpha(a) == isalpha(b)){
putc(a, ofp);
letters++;
}
}
return 0;
}
From what I have read, isalpha should check to see if the character is an alphabetical character but, in this instance is there something better for me to use? Thanks for any help you can give me!
This is the problem
if(isalpha(a) == isalpha(b)) {
it sould be
if (isalpha(a) && isalpha(b) && a == b)
You are not comparing whether the characters are equal, but instead you are comparing if both are alphabetic or not, in case they are both alphabetic or they are both NOT alphabetic the character will be printed to the file.
Also, get used to writing safe code which is also clean and readable, like the following (note that there are elegant methods to handle errors, and you can add error messages):
int main(int argc, char *argv[])
{
FILE *in[2];
FILE *out;
int chars[2]; // getc() returns `int' not `char'
int counter;
in[0] = fopen("input1a.txt", "r");
if (in[0] == NULL)
return -1;
in[1] = fopen("input1b.txt", "r");
if (in[1] == NULL) {
fclose(in[0]);
return -1;
}
output = fopen("output.txt", "w");
if (output == NULL) {
fclose(in[0]);
fclose(in[1]);
return -1;
}
counter = 0;
while (((chars[0] = getc(in[0])) != EOF) && ((chars[1] = getc(in[1])) != EOF) {
if (chars[0] == chars[1] && isalpha(chars[0])) {
putc(chars[0], out);
counter++;
}
}
// Release ALL resources, it's a good habit
fclose(inputs[0]);
fclose(inputs[1]);
fclose(output);
// Not required but a good habit too
return 0;
}
Don't use magic numbers, EOF is normally -1 but it's better to use EOF to make the code readable and robust.
This is making me nuts I am trying to make a simple program to copy any type of file using the following code but the result I get is unexpected (one or two extra characters at the end of copied file?). For instance if my original file has This is an example the copied file contains This is an exampleÿ
CODE
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fp,*fpp;
char pbuff, fname[32];
int i;
printf(" FILE NAME TO OPEN : ");
scanf(" %32s", fname);
fp = fopen(fname, "rb");
fpp = fopen("file", "wb");
if(fp==NULL)
{
printf("NO SUCH FILE. EXITING NOW.");
getch();
exit(1);
}
while(!feof(fp))
{
pbuff = fgetc(fp);
fputc(pbuff, fpp);
}
printf("SUCCESSFULLY CREATED!");
fclose(fp);
fclose(fpp);
getch();
return(0);
}
Can anyone help me out with this one? I will be really very thankful.
The reason is that feof (like most end-of-file indicators in most languages/environments) is only set AFTER the end-of-file has been reached. Since you write the character and only then check the EOF status, you're writing 1 too many characters. fgetc's return value is a predefined EOF if the end-of-file was reached during the call.
You could solve that in 1 of 2 ways:
while(true)
{
pbuff = fgetc(fp);
if(feof(fp))
break;
fputc(pbuff, fpp);
}
Or: (edit as melpomene correctly noticed!)
// Change pbuff to type int in the declartion, and then...
while(true)
{
pbuff = fgetc(fp);
if(EOF == pbuff)
break;
fputc(pbuff, fpp);
}
I am new to file IO in c. I decided to write a simple script in c that copies a file to a new file for practice:
#include <stdio.h>
void main(int argc, char* argv[])
{
if (argc != 3)
{
printf("Usage: ./myFile source destination");
exit(-1);
}
FILE * src = fopen(argv[1], "r");
if (src == NULL)
{
printf("source file not found", argv[1]);
exit(-1);
}
FILE* dest = fopen(argv[2], "w");
unsigned char c;
do {
c = fgetc(src);
fputc(c, dest);
} while (c != EOF);
}
However, I am getting an infinite loop. Is this because I never actually hit a character called EOF?
Also, is there a faster way to write this script aside from reading each character 1 at a time?
Declare c as an int and it'll work.
EOF is not a valid value for a character, because if it were, the presence of that character in a file could mislead code into thinking that file has ended when it actually hasn't. That's precisely why fgetc() actually returns an int, not a char.
Edit: Your code also has another bug: when fgetc() does return EOF, you pass that value to fputc() before ending the loop, causing an extra character to appear at the end of your output file. (The extra character will be whatever you get when you cast EOF to unsigned char on your system, typically character 255 == 0xFF == (unsigned char) -1.) To fix that, you can rewrite your loop like this:
int c;
while ((c = fgetc(src)) != EOF) {
fputc(c, dst);
}
or, if you don't like assigments in loop conditions:
while (1) {
int c = fgetc(src);
if (c == EOF) break;
fputc(c, dst);
}
Anyway, it would be much more efficient to read and write the data in chunks using fread() and fwrite(), e.g. like this:
unsigned char buf[65536];
while (1) {
int n = fread(buf, 1, sizeof(buf), src);
fwrite(buf, 1, n, dst);
if (n < sizeof(buf)) break; /* end of file or read error */
}
Also, it would be a good idea to include some error checking, since both reading and writing a file can fail for a variety of unexpected reasons. You can use ferror() to tell whether an error has occurred on a particular I/O stream.
EOF is not an unsigned char but an int. See the prototype of fgetc:
int fgetc(FILE *stream);