why fgetc() doesn't work well in my program (c language)? - c

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".

Related

C Programming - Copy File Buffer and Write to File

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");

Writing and reading CSV file in C wierd output

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.

C - FILE IO Read and Write Error

I am trying to swap the existing characters from the file with new characters one by one. The new characters are obtained by manipulating the existing characters by subtracting one from the ASCII code. The file already exists with text, but I ended up getting an infinite loop for some reason. What am I doing wrong?
#include <stdio.h>
int main()
{
FILE *fp = fopen("myfile.txt", "r+");
if (fp == NULL)
printf("File cannot be opened.");
else
{
// Used for retrieving a character from file
int c;
// Pointer will automatically be incremented by one after executing fgetc function
while ((c = fgetc(fp)) != EOF)
{
// Decrement pointer by one to overwrite existing character
fseek(fp, ftell(fp)-1, SEEK_SET);
// Pointer should automatically increment by one after executing fputc function
fputc(c-1, fp);
printf("%c\n", c);
}
fclose(fp);
}
return 0;
}
-EDIT-
I changed datatype of c from char to int, but problem still persisted. However, my problem has been resolved by adding fseek(fp, 0, SEEK_CUR) after fputc() call. I believe Jonathan Leffler's comment should become an answer since this kind of problem was not answered from the other question.
try this
#include <stdio.h>
int main(void){
FILE *fp = fopen("myfile.txt", "r+");
if (fp == NULL) {
printf("File cannot be opened.");
return -1;
}
int c;
long pos = ftell(fp);
while ((c = fgetc(fp)) != EOF){
fseek(fp, pos, SEEK_SET);//In the case of text file Do not operate the offset.
fputc(c-1, fp);
fflush(fp);//To save the output.
pos = ftell(fp);
printf("%c\n", c);
}
fclose(fp);
return 0;
}

Reading each char line by line in C

I was looking for a solution on how to read char by char on each line from a txt file and I found one, but I don't get some parts of the code. This is it:
#include <stdio.h>
#include <stdlib.h>
void handle_line(char *line) {
printf("%s", line);
}
int main(int argc, char *argv[]) {
int size = 1024, pos;
int c;
char *buffer = (char *)malloc(size);
FILE *f = fopen("myfile.txt", "r");
if(f) {
do { // read all lines in file
pos = 0;
do{ // read one line
c = fgetc(f);
if(c != EOF) buffer[pos++] = (char)c;
if(pos >= size - 1) { // increase buffer length - leave room for 0
size *=2;
buffer = (char*)realloc(buffer, size);
}
}while(c != EOF && c != '\n');
buffer[pos] = 0;
// line is now in buffer
handle_line(buffer);
} while(c != EOF);
fclose(f);
}
free(buffer);
return 0;
}
It was written by someone from here, but I can't reply 'cause I need more points lol. The parts I don't understand are:
if(c != EOF) buffer[pos++] = (char)c;
What does buffer[pos++] do? does it actually increase the variable "pos"? also, why does it start at 1 instead of 0? (pos starts at 0).
I can't really get track of the variable "pos", and I don't know why here buffer[pos] is 0:
buffer[pos] = 0;
The way I read the code is:
declare the size of the buffer that contains every char of every line (I mean, buffer is just free'd at the end, so it keeps the information on every line right?), then declare the other variables and alloc the memory of the buffer.
Open the file myfile.txt, and if it's not null, make pos = 0, then make "c" to store the first character of the file (now the function points to the next char), then if c != EOF meaning the end of file is not reached, save the character "c" in the position 1 of the buffer (I get confused here, why 1 and not 0). Then realloc twice as memory as before if needed. Do that for every character in the line untile you reach EOF or a \n. Now make buffer[pos] = 0, I dont know what value "pos" has, and I assume he makes buffer[pos] = 0 to indicate the end of the line? idk. Print the line, do that until you reach the end of the file. Close the file, free the memory on buffer.
Help! thanks.
fgetc(fp) - Reads the next character from the specified input stream (fp) and advances the associated file position indicator (you do not need to). If successful, the function will return the character read; otherwise, the value EOF (-1) is returned.
Here is a very simple example of using fgetc() to read each character of a file (and write it to another file using fputc())
char filename1[]={"c:\\play\\_in.txt"};//change paths as needed
char filename2[]={"c:\\play\\_out.txt"};
int main(void)
{
FILE *fp1 = {0};
FILE *fp2 = {0};
int c=0;
fp1 = fopen(filename1, "r");
if(fp1)
{
fp2 = fopen (filename2, "w");
if(fp2)
{
c = fgetc(fp1);
while(c != EOF)
{
fputc(c, fp2);
c = fgetc(fp1);
}
fclose(fp2);
}
fclose(fp1);
}
return 0;
}

Reading only first character of each line in file

I'm currently trying to read and process only first character in each line of a ".c" file. So far i have came to this code, but n is not even printed ot od the loop:
void FileProcess(char* FilePath)
{
char mystring [100];
FILE* pFile;
int upper = 0;
int lower = 0;
char c;
int n =0;
pFile = fopen (FilePath , "r");
do {
c = fgetc (pFile);
if (isupper(c)) n++;
} while (c != EOF);
printf("6");
printf(n);
fclose (pFile);
}
A few points:
You are not printing n correctly. You are feeding it to printf as the "formatting string". It is surprising that you get away with it - this would normally cause havoc.
You are reading one character at a time. If you want to print only the first character of each line, better read a line at a time, then print the first character. Use fgets to read entire line into a buffer (make sure your buffer is big enough).
Example (updated with inputs from #chux - and instrumented with some additional code to aid in debugging the "n=1" problem):
void FileProcess(char* FilePath)
{
char mystring [1000];
FILE* pFile;
int upper = 0;
int lower = 0;
char c;
int n =0;
pFile = fopen (FilePath , "r");
printf("First non-space characters encountered:\n")
while(fgets( myString, 1000, pFile) != NULL)
int jj = -1;
while(++jj < strlen(myString)) {
if ((c = myString[jj]) != ' ') break;
}
printf("%c", c);
if (isupper(c)) {
printf("*U*\n"); // print *U* to show character recognized as uppercase
n++;
}
else {
printf("*L*\n"); // print *L* to show character was recognized as not uppercase
}
}
printf("\n");
printf("n is %d\n", n);
fclose (pFile);
}
NOTE there are other more robust methods of reading lines to make sure you have everything (my favorite is getline() but it is not available for all compilers) . If you are sure your code lines are not very long, this will work (maybe make the buffer a bit bigger than 100 characters though)

Resources