Any idea why I get 0.000000 with this printf? I checked the file and it was created fine
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
double doub1;
FILE *p;
if((p=fopen("data.txt","wb+"))==NULL)
puts("no");
fprintf(p,"%lf#%lf\n%lf%s",3.9458,314.32133,32.3,"hello");
fscanf(p,"%lf",&doub1);
printf("%lf",doub1);
}
To write to a stream opened with + and read from the same stream you need to flush the output first:
fflush(p);
However this does not reposition the file position indicator. To read characters you already wrote, you need to seek back to them. There is not a separate file position indicator for reading and writing:
fseek(p, 0, SEEK_SET); // go to start of file
The fseek does an implicit flush so you don't need to do fflush if you are doing fseek.
Also, you should check the return value of fscanf before trying to print the output. If the scan failed then you are printing an uninitialized variable.
Related
I am new to the C programming language. I am learning file I/O, and am confused with the fseek function. Here is my code
#include <stdio.h>
#include <stdlib.h>
struct threeNumbers {
int n1,n2,n3;
}
int main (){
int n;
struct threeNumbers number;
FILE *filePointer;
if ((filePointer=fopen("\\\\wsl$\\Ubuntu-20.04\\home\\haseeb\\learningC\\file Input and Output\\program2\\program.bin","rb"))==NULL){
printf("error! opening file);
/* if pointer is null, the program will exit */
exit(1);
}
/* moves the cursore at the end of the file*/
fseek(filePointer,-sizeof(struct threeNumbers),SEEK_END);
for(n=1;n<5;++n){
fread(&number,sizeof(struct threeNumbers),1,filePointer);
printf (" n1:%i\tn2:%i\tn3:",number.n1,number.n2,number.n3);
fseek(filePointer,-2*sizeof(struct threeNumbers),SEEK_CUR);
}
fclose(filePointer);
return 0;
}
I know that this program will start reading the records from the file program.bin in the reverse order (last to first) and prints it.
my confusion is I know that "fseek(filePointer,-sizeof(struct threeNumbers),SEEK_END);" will move the cursor at the end of the binary file. What does "fseek(filePointer,-2*sizeof(struct threeNumbers),SEEK_CUR);" do? I think it moves to the current location, but what is the point of the cursor cumming to the current location in this program? Also why is it -2 instead of being just "-sizeof(struct threeNumbers)"?
Disregarding the actual code, this is what fseek() does:
The fseek() function sets the file position indicator for the stream
pointed to by stream. The new position, measured in bytes, is obtained
by adding offset bytes to the position specified by whence. If whence
is set to SEEK_SET, SEEK_CUR, or SEEK_END, the offset is relative to
the start of the file, the current position indicator, or end-of-file,
respectively. A successful call to the fseek() function clears the
end-of-file indicator for the stream and undoes any effects of the
ungetc(3) function on the same stream.
fseek(filePointer,-sizeof(struct threeNumbers),SEEK_END) will not "move the cursor at the end of the binary file"; it will move it sizeof(struct threeNumbers) before the end of the file.
I am facing this strange problem, answer to which is clear to me but I am looking for alternative here. Whenever I open a file in "a+" mode, I am able to read using fread(), if I read it first and then write in it using fprintf(). If I instead write into file first and then read it, I get blank value in output.
I do not want to fclose() the FILE pointer fp after every write because I am doing operations like write->read->write->read.......n iterations.
Is there an optimal way to achieve this ?
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <poll.h>
#include <linux/input.h>
int main(){
FILE * fp;
fp = fopen("myback.txt", "a+");
char buf[10];
fprintf(fp, "checking");
fread (buf,1,4,fp);
buf[4] = '\0'; //buf has read n bytes
printf("%s \n", buf);
return 0;
}
From this fopen reference:
In update mode ('+'), both input and output may be performed, but output cannot be followed by input without an intervening call to fflush, fseek, fsetpos or rewind, and input cannot be followed by output without an intervening call to fseek, fsetpos or rewind, unless the input operation encountered end of file. In update mode, implementations are permitted to use binary mode even when text mode is specified.
So you can't read or write directly after each other, you must explicitly set or reset the file position between each input and output function.
I'm trying to read a txt file containing strings of 1s and 0s and print it out in the manner below. I tried my code a couple of months ago and it worked fine in reading the text file. Now when I tried it, it outputs something really strange. Also I tried changing the directory of the file to a non-existant file but it still outputs the same thing when it should've quit the program immediately. Please help!
The content of txt file:-
10000001
01110111
01111111
01111010
01111010
01110111
Expected output:-
data_in<=24'b10000001;
#10000;
Real output:-
data_in<=24'b(some weird symbol that changes everytime I recompile);
#10000;
My code:-
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (int argc, char *argv[])
{
int i, j;
j = 0;
char words[50];
FILE *fp;
fp = fopen (argv[1], "r");
if (fp == NULL) {
printf ("Can't open file\n");
}
while (feof (fp) == 0) {
fscanf (fp, "%s", words);
printf ("data_in<=24'b%s\n", words);
printf ("#10000\n");
}
fclose (fp);
system ("PAUSE");
return 0;
}
The input argument is the following:-
"C:\Users\Beanz\Documents\MATLAB\football frame\frame1.txt"
Read each line one by one with getline(3) -if available- or with fgets (you'll then need a large enough line buffer, at least 256 bytes), then parse each line buffer appropriately, using sscanf (the %n might be useful, and you should test the scanned item count result of sscanf) or other functions (e.g. strtok, strtol, etc...)
Remember that 'feof()' is only set AFTER trying to read PAST the end of the file, not when at the end of the file.
So the final iteration through the loop will try to read/process data that contains trash or prior contents.
Always check the returned value from 'fscanf()' before trying to use the associated data.
strongly suggest
eliminate the call to feof() and use the fscanf() to control the loop
In the file "file1.dat" I wrote "anahasapples". And then I wrote this program:
#include <stdio.h>
#include <conio.h>
int main()
{
FILE *ptr_file;
ptr_file=fopen("file1.dat","r+");
printf("%c",fgetc(ptr_file));
printf("%c",fgetc(ptr_file));
printf("%c\n",fgetc(ptr_file));
char c;
printf("char:\n");
c=getch();
fputc(c,ptr_file);
return 0;
}
The part where I print the first 3 characters from the file works. After that, I want to put a char into the file. When I compile this, I don't get any errors, but the containing text doesn't change.
Documentation for fopen() standardly shows the following explanation:
When a file is opened with update mode (+ as the second or third
character in the mode argument), both input and output may be
performed on the associated stream. However, output must not be
directly followed by input without an intervening call to fflush(3C)
or to a file positioning function (fseek(3C), fsetpos(3C) or
rewind(3C)), and input must not be directly followed by output without
an intervening call to a file positioning function, unless the
input operation encounters end-of-file.
Just add an fseek() to your code and all works well:
#include <stdio.h>
#include <conio.h>
int main()
{
FILE *ptr_file;
ptr_file=fopen("file1.dat","r+");
printf("%c",fgetc(ptr_file));
printf("%c",fgetc(ptr_file));
printf("%c\n",fgetc(ptr_file));
char c;
printf("char:\n");
c=getch();
fseek( ptr_file, 0, SEEK_CUR ); /* Add this line */
int err = fputc(c,ptr_file);
printf ("err=%d\n", err);
return 0;
}
Here's my file1.dat before and after inputting an 'x':
Before
anahasapples
After
anaxasapples
It seems that by default the fputc() tries to write past the end of the file, so you need to reposition the file pointer (e.g., using fseek) to make the write occur at the point of the current file pointer.
set the pointer first
fseek(ptr_file, ftell (ptr_file), SEEK_SET);
fputc(c,ptr_file);
See this link for explanation http://cplus.about.com/od/learningc/ss/files_8.htm
http://www.rainydayz.org/beej/bgc/fseek.html
I wanted to write, read and print to and from the same file. But when the program executes, it can write but it can't read or print the data I have written. When I execute the program, it stops working after writing to the file. I have verified that the file (penny.txt) contains data after the write operation.
I don't know where this is going wrong - how can I read and print the data?
I'm quite new to this, so please take that in mind when answering.
#include<stdio.h>
int main()
{
char ch;
char penny[50],pen[50];
FILE *Object;
Object = fopen("Penny.txt","w+");
fgets(penny, sizeof penny, stdin);
fprintf(Object,penny);
fscanf(Object,"%s",pen);
printf("%s",pen);
return 0;
}
You're at the end of the file when you call fscanf(). Use fseek to return to the beginning:
/* this ignores a whole host of other issues */
fprintf(Object,penny);
/* optional: fflush(Object); */
/* after the call to fprintf you're at the end of the "stream" in this case,
* go back to the beginning:
*/
fseek(Object, 0, SEEK_SET);
/* now we have something to read! */
fscanf(Object,"%s",pen);
printf("%s\n",pen);
You did not notice this problem due to a complete lack of error checking. fopen, fprintf, and fscanf all have error conditions listed, and all use their return value to signal a problem. You ignore these return values at your own peril.
#include<stdio.h>
int main()
{
//char ch;//unused!
char penny[50],pen[50];
FILE *Object;
Object = fopen("Penny.txt","w+");
fgets(penny, sizeof penny, stdin);
fprintf(Object,"%s", penny);//it troubled indicator(%) is included
fflush(Object);//Buffer flush : So that there is no wrote
rewind(Object);//rewind the position of access to the file
fscanf(Object,"%s",pen);
printf("%s",pen);
return 0;
}
You need to Use fseek() to move back the file current position inside the file.
int fseek ( FILE * stream, long int offset, int origin );
Reposition stream position indicator
Sets the position indicator associated with the stream to a new position.
stream
Pointer to a FILE object that identifies the stream.
offset
Binary files: Number of bytes to offset from origin.
Text files: Either zero, or a value returned by ftell.
origin
Position used as reference for the offset. It is specified by one of the following constants defined in exclusively to be used as arguments for this function:
Constant Reference position
SEEK_SET Beginning of file
SEEK_CUR Current position of the file pointer
SEEK_END End of file
*
try this:
#include<stdio.h>
int main()
{
char ch;
char penny[50],pen[50];
FILE *Object;
Object = fopen("Penny.txt","w+");
fgets(penny, sizeof penny, stdin);
fprintf(Object,penny);//now the file is in EOF
fseek(Object,-1*(strlen(penny),SEEK_CUR);//<===move back |penny| in the file
/* optional or:fseek(Object,0,SEEK_SET);<===move to start of file */
fscanf(Object,"%s",pen);
printf("%s",pen);
return 0;
}