counting file characters with fseek - c

i want to count file chars like this :
#include <stdio.h>
#include <stdlib.h>
int main(){
int d=0;
char filename[25];
FILE *file;
printf("Enter file name to be read (Text File!) : ");
gets(filename);
file = fopen(filename, "rt");
if(file == NULL){
printf("Failed to open file...");
exit(1);
}
fseek(file, 0L, SEEK_SET);
while( !feof(file) ){
fseek(file, 1L, SEEK_CUR);
d++;
}
printf("%d", d);
}
after that im printing d and it value is 0..
and the file dose have chars. about 150 chars..

fseek() allows you to seek beyond the mark of EOF.
To get the file size, you could fseek(file, 0, SEEK_END) and then call ftell(file).
To read character by character, you could use for (i = 0; fgetc(file) != EOF; i++);.

I'm wondering if the program ever returns, as per fseek()'s documentation feof() shall never return anything <>0:
A successful call to the
fseek() function clears the end-of-file indicator for the stream
To determine the file size using fseek() do:
FILE * pf = ...;
fseek(pf, 0, SEEK_END);
long size = ftell(pf);

i did it like this at the end and it work.
fseek(file, 0, SEEK_END);
and then call
ftell(file);
befor i tryed to do it like that :
for (i = 0; fgetc(file) != EOF; i++);
and it didnt worked...but now it is 0.0
Thank you all..!

Related

C text inverting always prints unwanted '%' in the end [duplicate]

This question already has an answer here:
linux terminal output redundant content
(1 answer)
Closed 9 months ago.
I have this small code that is only inverting the text in a file character by character and its working perfectly fine, the problem is that it always adds a '%' at the end.
FILE *fd;
int main (int argc, char *argv[]) {
if ((fd = fopen(argv[1], "r")) != NULL){
int ft = 0;
int i = 0;
fseek(fd, 0, SEEK_END);
ft = ftell(fd);
while(i < ft)
{
i++;
fseek(fd, -i, SEEK_END);
printf("%c", fgetc(fd));
}
printf(" ");
fseek(fd, 0, SEEK_END);
fclose(fd);
}
else {
perror ("File does not exist !!!\n\a");
}
return 0;
}
The input text is : Taco cat
And the output is : tac ocaT %
So i can't find a way to get rid of this pesky % sign.
Im in linuxmint.
The % is your shell prompt. It's not from the program. The reason it looks weird is that you forgot to print a \n at the end of the string.
For using FILE include <stdio.h> header.
checking for file opening can be go outside if statement it makes more readable.
After finish work add a \n to output.
the code so far
#include <stdio.h>
int main(int argc, char *argv[]) {
FILE *fd = fopen(argv[1], "r");
if (fd == NULL) {
perror("File does not exist !!!\n\a");
}
int ft = 0;
int i = 0;
fseek(fd, 0, SEEK_END);
ft = ftell(fd);
while (i < ft) {
i++;
fseek(fd, -i, SEEK_END);
printf("%c", fgetc(fd));
}
printf(" ");
fseek(fd, 0, SEEK_END);
fclose(fd);
printf("\n");
return 0;
}
For more accuracy check result of fseek() which is return zero on success.
Here grab from manpage, man fseek.
RETURN VALUE
The rewind() function returns no value. Upon successful completion, fgetpos(), fseek(), fsetpos() re‐
turn 0, and ftell() returns the current offset. Otherwise, -1 is returned and errno is set to indi‐
cate the error.

Broken files in C

I made a simple script to rewrite one file contents into another.
Here's code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char filename[1024];
scanf("%s", &filename);
// printf("Filename: '%s'\n", filename);
int bytesToModify; scanf("%d", &bytesToModify);
FILE *fp;
fp = fopen(filename, "r");
fseek(fp, 0, SEEK_END);
int fSize = ftell(fp);
fseek(fp, 0, SEEK_SET);
printf("%d\n", fSize);
char *buf = malloc(fSize*sizeof(char));
for (int i = 0; i < fSize; i++) {
buf[i] = getc(fp);
}
fclose(fp);
FILE *fo;
fo = fopen("out_file.txt", "w");
for (int i = 0; i < fSize; i++) {
fwrite(&buf[i], 1, 1, fo);
}
fclose(fo);
return 0;
}
Even on small file like this I can see the artifact. Cyrillic sybmol 'я' is coming in the end of file.
If I'll try to rewrite executable file, i get this:
99% of file just turned to these symbols. What is wrong with my code?
I'm using CodeBlocks with GCC Compiler, version 10.1.0.
My Operation System is Windows 10.
Thanks for your help.
You did not open the file in binary mode: "rb" and "wb". Therefore, fgetc will turn all \r\n to a single \n.
For each line terminator there is one character less read. Yet you attempt to read nevertheless, and fgetc will return EOF (and fgetc returns an int, not char). As EOF has value -1 on Windows, when written to file converted to unsigned char this results in Я in the encoding you're using in Notepad (most likely Windows-1251).
Furthermore, since you're using fwrite, then you could similarly use fread. And no need to read, write the characters one at a time, just use
char *buf = malloc(fSize);
int bytesRead = fread(buf, 1, fSize, fp);
fclose(fp);
and
int bytesWritten = fwrite(buf, 1, bytesRead, fo);

Getting excess characters with fread() in C

Okay, so I have tried to read a whole file with fread(), and I can do it successfully, but the longer the file, the more the excess characters I get on the output.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main() {
FILE* fpointer = fopen("test.txt", "r");
char* wholeFile;
long int fileSize;
if (fpointer == NULL) return 0;
fseek(fpointer, 0, SEEK_END);
fileSize = ftell(fpointer);
rewind(fpointer);
printf("fileSize == %ld\n", fileSize);
wholeFile = (char*)malloc(fileSize+1, sizeof(char));
if (wholeFile == NULL) return 1;
fread(wholeFile, sizeof(char), fileSize, fpointer);
fclose(fpointer);
wholeFile[fileSize] = '\0';
printf("This is whole file:\n\n%s", wholeFile);
free(wholeFile);
return 0;
}
If the file looks like this:
This is cool file.
I get this as output:
This is cool file.²²²²
And if the file is like this:
This
is
cool
file.
I get this as the output:
This
is
cool
file.═══²²²²
Any idea where I'm wrong?
EDIT: Edited code according to comments.
You need to allocate one more than the size of the file and set the last position in the buffer to 0.
C expects character arrays to be null terminated.
Use "rb" to open the file in binary mode. This will ensure you get a reliable count of bytes in the file from Windows.
FILE* fpointer = fopen("test.txt", "rb");
wholeFile = (char*)malloc(fileSize + 1);
wholeFile[fileSize] = '\0';

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

Usage of fseek and feof

I this code is used for reading the text file in reverse order. And it successful does, displaying the original content of file and the reversed content of file.
#include <stdio.h>
#include <stdlib.h>
int main() {
int count = 0, ch = 0;
FILE *fp;
if( (fp = fopen("file.txt", "r")) == NULL ) {
perror("fopen");
exit(EXIT_FAILURE);
}
printf("\tINPUT FILE\n");
printf("\n");
while(!feof(fp)) {
if((ch = getc(fp)) != EOF) {
printf("%c", ch);
count ++;
}
}
feof(fp);
printf("\n");
printf("\tREVERSED INPUT FILE\n");
printf("\n");
while(count) {
fseek(fp, -2, SEEK_CUR);
printf("%c", getc(fp));
count--;
}
printf("\n");
fclose(fp);
}
But when i replaced, this piece of code
while(!feof(fp)) {
if((ch = getc(fp)) != EOF) {
printf("%c", ch);
count ++;
}
}
by
fseek (fp, 0, SEEK_END); or feof(fp);
Basically i just went till end of file and directly without printing the original contents of file and tried printing the reversed content of file.
But for it does not print the reversed content filed either !!! it just display blank. Why is this happening ??
NOTE: fseek(fp, -2, SEEK_CUR); Have done this (in another while loop) as getc(fp) moves fp forward by one so need to rewind it back by two, also initially it will be pointing to EOF
What is happening here? Can any one please explain?
It breaks because the second loop is while (count), and count is zero if you haven't read through the file first while incrementing it. You can use ftell to obtain the equivalent of count in this case.
P. S. feof(fp) only tests whether fp is at end-of-file, it does not make it seek to EOF, so the line feof(fp) basically does nothing since you aren't using the return value.
As #Arkku already showed, when you replace the while loop with fseek(SEEK_END), count will not be incremented.
To fix this, you can use ftell after fseek, which returns the file length
fseek(fp, 0, SEEK_END);
count = ftell(fp);
Now the file will be printed backwards.

Resources