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.
Related
I wrote this code where I generate random integers in a large quantity and store them in a txt file. it works if I input up to 49 integers
but after that it does not read any further from the file or the file don't accept any further I don't know please help me
this is the code
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
FILE *fptr;
int num, n;
fptr = fopen("integers.txt", "w");
if (fptr != NULL)
{
printf("File created successfully!\n");
}
else
{
printf("Failed to create the file.\n");
return -1;
}
printf("Enter some integer numbers [Enter -1 to exit]: ");
scanf("%d", &n);
while (n != 0)
{
num = rand();
putw(num, fptr);
n--;
}
fclose(fptr);
fptr = fopen("integers.txt", "r");
printf("\nNumbers:\n");
int count = 0;
while ((num = getw(fptr)) != EOF)
{
printf("%d\n", num);
count++;
}
printf("\nNumber of elements in the file %d",count);
fclose(fptr);
return 0;
}
You have following problems:
As you're writing binary data, the file needs to be opened with "wb" and "rb" (b stands for binary). Othwerwise certain unwanted text substitutions will take place.
If one of your random numbers turns out to be -1, the read will stop prematurely because EOF has the value -1. Therefore you need to do the end of file check with the feof function instead of comparing the value read with EOF.
fptr = fopen("integers.txt", "wb"); // <<< open with binary mode "wb"
...
fptr = fopen("integers.txt", "rb"); // <<< open with binary mode "rb"
printf("\nNumbers:\n");
int count = 0;
while (1)
{
num = getw(fptr);
if (feof(fptr)) // end of file reached => stop the loop
break;
printf("%d\n", num);
count++;
}
BTW:
The documentation of getw concerning the return value is pretty misleading, especially the part "A return value of EOF indicates either an error or end of file" seems wrong to me. getw can read -1 values (0xffffffff) without problems.
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);
I'm writing a program that asks the user for a file name, and creates it if it doesn't exist. At the end of the program, I want to check if the created program is empty, and if it is, delete it. Not deleting it and then running the program with that same file name messes up the way the input is detected.
I've tried using rewind() to go back to the beginning and then checking feof() to see if the beginning of the file was the EOF character, but that didn't work.
Then, I did some searching online, and found a method that used fseek() to go to the end of the file, and then checked with ftell() whether the end of the file was at position 0, but again this did not work.
I went back and did more poking around, and found that the problem might be because I hadn't used fclose() first, so I tried the previous two attempted solutions again, this time being sure to close the file before trying to delete it. Still no dice.
I tried checking what errno was set to, and got 2: No such file or directory. This is patently false, since if that was the case, it would mean that I had accomplished my goal, and when I check the working directory, the file is still there.
I have absolutely no idea what to try next. Can anyone point me in the right direction?
Here are the ways I've tried to delete the file (fp is the file pointer, and file is a char pointer with the name of the file that fp points to.) :
Attempt 1:
rewind(fp);
if(feof(fp)){
remove(file);
}
Attempt 2:
fseek(fp, 1, SEEK_END);
long size = ftell(fp);
if(size == 0){
remove(file);
}
Attempt 3:
fseek(fp, 1, SEEK_END);
long size = ftell(fp);
fclose(fp);
if(size == 0){
remove(file);
}
Attempt 4:
rewind(fp);
int empty = 0;
if(feof(fp)){
empty = 1;
}
fclose(fp);
if(empty == 1){
remove(file);
}
UPDATE: Here's a couple MCVEs, one for each method.
#include <stdio.h>
#include <errno.h>
int main() {
FILE *fp;
char file[40];
scanf(" %[^\n]s", file);
fp = fopen(file, "r");
if(fp == NULL){
fp = fopen(file, "w");
int result;
rewind(fp);
int empty = 0;
if(feof(fp)){
empty = 1;
}
fclose(fp);
if(empty == 1){
result = remove(file);
}
printf("%d\n", result);
printf("%d\n", errno);
return 0;
}
Version 2:
#include <stdio.h>
#include <errno.h>
int main() {
FILE *fp;
char file[40];
scanf(" %[^\n]s", file);
fp = fopen(file, "r");
if(fp == NULL){
fp = fopen(file, "w");
int result;
fseek(fp, 1, SEEK_END);
long size = ftell(fp);
fclose(fp);
if(size == 0){
result = remove(file);
}
printf("%d\n", result);
printf("%d\n", errno);
return 0;
}
UPDATE 2:
I just realized that when I was making the MCVEs, when I ran them, result was returning 0, which should have meant that it was successful, but the file was still there in the directory. I'm at a loss for words.
The code wasn't reaching the remove statement.
I'm trying to read the hex values from an image file using C. In Linux, this code works fine, but with Windows it reads only the first 334 bytes and I don't understand why.
The code to read the file is:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
void readHexFile(char* path) {
FILE *fp;
if ((fp = fopen (path, "r")) != NULL) {
struct stat st;
stat(path, &st);
int i;
int ch;
for (i = 0; i < st.st_size; i++) {
ch = fgetc(fp);
printf("%x ", ch);
}
fclose(fp);
}
else {
return NULL;
}
}
st.st_size comes from <sys/stat.h> package and contains the right value (the size, in bytes, of the image file)
This image show what my program outputs, and the actual binary content of the file it is reading:
As you see after the sequence of 17, 18, 19 there is also hex values but my program prints ffffffff repeatedly.
You opened the file in a text mode, and not as binary. Different platforms may behave differently.
In this case, Microsoft Windows decided that this plain text file ends at the first occurrence of Ctrl+Z (0x1A), and returns EOF for all fgetc afterwards.
Explicitly state that you want to open the file as binary:
fp = fopen ("yourfile", "rb");
and the problem goes away.
I think your loop should look like this:
int ch;
while (!feof(fp)) {
ch = fgetc(fp);
printf("%x ", ch);
}
It's completely unclear to me why you are using st.st_size here.
On Windows, the character 0x1A (Ctrl+Z) is the EOF character for text mode; see this question.
If you're reading from a binary file like a JPEG, you should do so with first opening the file as binary (fopen mode "rb"), then fread into a pre-allocated buffer, the size of which you would determine with ftell with the file pointer at the end of the file:
size_t i, len;
char *buffer = NULL;
fp = fopen(argv[1], "rb");
if(!fp)
// handle error
fseek(fp, 0, SEEK_END);
len = ftell(fp);
rewind(fp);
buffer = malloc(len + 1);
if(!buffer)
// handle error
fread(buffer, 1, len, fp);
for(i = 0; i < len; i++)
{
printf("%.2X ", buffer[i]);
}
free(buffer);
buffer = NULL;
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..!