#include <stdio.h>
#include <stdlib.h>
#define FILE_NAME "ff.txt"
int main() {
char x[10],y[10];
FILE *fp;
fp = fopen(FILE_NAME, "r+");
if (fp == NULL) {
printf("couldn't find %s\n ",FILE_NAME);
exit(EXIT_FAILURE);
}
fprintf(fp,"Hello2 World\n");
fflush(fp);
fscanf(fp,"%s %s",x,y);
printf("%s %s",x,y);
fclose(fp);
return 0;
}
Here's a boiled down version of what I am trying to do. This code doesn't print anything in the console. If I remove the fprintf call, it prints the first 2 strings in the file, for me its Hello2 World. Why is this happening? Even after I fflush the fp?
After fprintf(), the file pointer points to the end of the file. You can use fseek() to set the filepointer at the start of the file:
fprintf(fp,"Hello2 World\n");
fflush(fp);
fseek(fp, 0, SEEK_SET);
fscanf(fp,"%s %s",x,y);
Or even better as suggested by #Peter, use rewind():
rewind(fp);
rewind:
The end-of-file and error internal indicators associated to the stream
are cleared after a successful call to this function, and all effects
from previous calls to ungetc on this stream are dropped.
On streams open for update (read+write), a call to rewind allows to
switch between reading and writing.
It is always best to check the return code of fscanf() too.
To avoid buffer overflow, you can use:
fscanf(fp,"%9s %9s",x,y);
Related
Just testing out file descriptors. My aim is to open up a file stream with fopen and using fprintf write the file descriptors integer value back into the file to see what results im getting.
(I decided using fopen, fprintf etc) as it allowed me to write in variables, write() wouldn't allow it,
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
int main ()
{
FILE *fp;
fp = fopen("wow.txt", "w+");
if (fp < 0)
{
printf("ERROR \n");
}
else
{
printf("we good \n");
}
fprintf(fp, "hi %p \n", fp);
}
Issue i am facing is, if i write %d for the fprintf statement...i get a compiler error. If i write %p, I get the address in RAM.
Is it possible to get the absolute integer value...like "3"
FILE *fp;
is not a file descriptor, it's a file stream pointer and, as such, you need to treat it as a pointer.
A file descriptor is a small integer returned from one of the UNIXy calls like open or creat, while file pointers are sort of a level above that, assuming you're in an environment that even has descriptors.
In those environments, you can generally get at the underlying descriptor with something like:
int fd = fileno (fp);
The following complete program (under CygWin) shows this in action:
#include <stdio.h>
int main (void) {
FILE *fp = fopen ("wow.txt", "w+");
if (fp < 0) {
printf ("ERROR\n");
return 1;
}
fprintf (fp, "fp=%p, fd=%d\n", fp, fileno (fp));
fclose (fp);
return 0;
}
Compiling that with:
gcc -o testprog testprog.c
gives the output:
fp=0x800102a8, fd=3
I'm testing out the basic functions to operate files with.
I try to first open/close a file to create it, and then open/close it again to append to it. Lastly, I print out what is in the file.
My code currently looks like the following:
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE * file;
char mark;
/* WRITING: */
file= fopen("goodbye.c","w");
if(!file)
{ printf("Couldn't open file.\n");
exit(EXIT_FAILURE); }
printf("Enter data to write to .c file:");
while((mark= getchar())!=EOF)
{
putc(mark,file);
}
fclose(file);
/* APPENDING: */
file= fopen("goodbye.c","a");
if(!file)
{ printf("Couldn't open file.\n");
exit(EXIT_FAILURE); }
char add;
scanf("%c",add);
putc(add,file);
fclose(file);
/* READING: */
file= fopen("goodbye.c","r");
if(!file)
{ printf("Couldn't open file.\n");
exit(EXIT_FAILURE); }
while((mark= getc(file))!= EOF)
{
printf("%c",mark);
}
fclose(file);
}
With this, I'm not able to append to the file. When using getchar(), I type ctrl+d once finished writing in the first place. After this it goes on to printing out what I just wrote, not giving me the chance to append to the file. Does ctrl+d somehow interrupt with scanf?
And how to get the result that I was looking for?
Your code only allows you to append a single character to the file, which is a little stingy. It can also (at least in theory) lead to problems on some systems if the last line of the text file does not end with a newline, which it won't if you add something other than a newline. Maybe you need a loop to read multiple characters?
Also, since you don't stop the initial input until EOF, you need to clear the 'error' on stdin with clearerr(stdin) to allow further input to occur. This works correctly on Mac OS X 10.10.1 Yosemite; it should work the same on other Unix systems. I can't answer confidently for Windows-based code unless it is using something like Cygwin to simulate Unix, but I expect it would work in much the same way there, too, even with MSVC.
Incidentally, my compiler complains about a missing & in the call to scanf() at:
char add;
scanf("%c",add);
If your compiler doesn't complain, either turn up the warning level or get a better compiler.
This code works as I'd expect:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
FILE *file;
char mark;
/* WRITING: */
file = fopen("goodbye.c", "w");
if (!file)
{
printf("Couldn't open file.\n");
exit(EXIT_FAILURE);
}
printf("Enter data to write to .c file:");
while ((mark = getchar()) != EOF)
{
putc(mark, file);
}
fclose(file);
printf("EOF 1\n");
/* APPENDING: */
file = fopen("goodbye.c", "a");
if (!file)
{
printf("Couldn't open file.\n");
exit(EXIT_FAILURE);
}
clearerr(stdin);
char add;
while (scanf("%c", &add) == 1)
putc(add, file);
fclose(file);
printf("EOF 2\n");
/* READING: */
file = fopen("goodbye.c", "r");
if (!file)
{
printf("Couldn't open file.\n");
exit(EXIT_FAILURE);
}
while ((mark = getc(file)) != EOF)
{
printf("%c", mark);
}
fclose(file);
return 0;
}
The only substantive changes are adding a loop around the scanf() — though frankly it would be better to use getchar() again, like in the first input loop — fixing the call to scanf(), adding the two printf() statements that report when EOF is detected, and including clearerr(stdin); to allow input to continue.
Sample output
Code without clearerr(stdin):
Enter data to write to .c file:Happiness is a bug-free program.
Happiness is seldom attained.
EOF 1
EOF 2
Happiness is a bug-free program.
Happiness is seldom attained.
Code with clearerr(stdin):
Enter data to write to .c file:Happiness is a bug-free program.
Happiness is seldom attained.
EOF 1
But it helps when you add the clearerr(stdin) to this one.
EOF 2
Happiness is a bug-free program.
Happiness is seldom attained.
But it helps when you add the clearerr(stdin) to this one.
I have an embedded board (beagleboard-xm) that runs ubuntu 12.04. I need to read a GPIO continuously to see if the value of the port changes. My code is herebelow:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
FILE *fp;
int main(void)
{
//linux equivalent code "echo 139 > export" to export the port
if ((fp = fopen("/sys/class/gpio/export", "w")) == NULL){
printf("Cannot open export file.\n");
exit(1);
}
fprintf( fp, "%d", 139 );
fclose(fp);
// linux equivalent code "echo low > direction" to set the port as an input
if ((fp = fopen("/sys/class/gpio/gpio139/direction", "rb+")) == NULL){
printf("Cannot open direction file.\n");
exit(1);
}
fprintf(fp, "low");
fclose(fp);
// **here comes where I have the problem, reading the value**
int value2;
while(1){
value2= system("cat /sys/class/gpio/gpio139/value");
printf("value is: %d\n", value2);
}
return 0;
}
the code above reads the port continuously (0 by default), however, when I change the port as 1, system call output the correct value, however printf still prints 0 as an output. What is the problem with value2 that does not store the value that system() outputs.
If I use the code below instead of while loop above, I get an error about opening the value file (Cannot open value file.), if I put the fopen line outside of while loop, it does not show the changes in the value file.
char buffer[10];
while(1){
if ((fp = fopen("/sys/class/gpio/gpio139/value", "rb")) == NULL){
printf("Cannot open value file.\n");
exit(1);
}
fread(buffer, sizeof(char), sizeof(buffer)-1, fp);
int value = atoi(buffer);
printf("value: %d\n", value);
}
My question: how do I need to fix the code? or how should I read the value file?
As an additional info that I wonder: what is the difference to e.g. export the port by system("echo 139 > /sys/class/gpio/export") and fp = fopen("/sys/class/gpio/export","w"); fprintf(fp,"%d",139); which method do you suggest me to use? Why?
Thank you in advance.
The system() function returns the return value of cat, which is 0. It does not return the standard output from cat, which is what you were expecting.
I think the problem with your second bit of code is that you're not calling fclose(). Since you're running in a tight loop, you almost immediately exceed the number of open files allowed.
So, call fclose(), and think about putting a sleep() in there too.
When reading a file in C, your position in the file changes as you read it. For example, if you were to open a file with the contents:
First Line
Second Line
Third Line
and run this program:
char buffer[1024];
while(fgets(buffer, sizeof(buffer), theFile))
{
printf("Buffer: %s", buffer);
}
It would print:
First Line
Second Line
Third Line
As you read each line, the position in the file changes to the next line.
In your program, after reading the value the first time, you are trying to read the empty space in the file, instead of the value you want.
The solution to your problem is to move fopen outside of the while loop, but call fseek to reset your position to the start of the file each time through the loop.
To use fseek, you need to pass it a file pointer, byte offset and seek point. Here you call it on your file, with a 0 byte offset from the waypoint SEEK_SET, which indicates the start of the file.
fseek(theFile, 0, SEEK_SET);
Suppose I have a string char* str.
I print it to the buffer in the following way:
char buf[MAX_LEN];
freopen("tmp","w",stdout);
printf("%s\n",str);
fflush(stdout);
fp = fopen(tmp,"r");
if (fp == NULL) return;
fgets(buf,MAX_LEN,fp);
fclose(fp);
fclose(stdout);
May this code cause invalid stream buffer handle?
Is it legal to use freopen and after it fopen?
Based on constrains of my system I can't use fprintf and sprintf.
In theory, it's perfectly legal and works fine. It's even its main use case, according to its man page :
The freopen() function opens the file whose name is the string
pointed to by path and associates the stream pointed to by stream with
it. The original stream (if it exists) is closed. The mode argument
is used just as in the fopen() function. The primary use of the
freopen() function is to change the file associated with a standard
text stream (stderr, stdin, or stdout)
In practice, your code won't work : there are some mistake mainly between "tmp" and tmp & missing headers. This code will work:
#include <stdio.h>
#define MAX_LEN 512
int main() {
const char* str = "data\n";
FILE* fp;
char buf[MAX_LEN];
freopen("tmp","w",stdout);
printf("%s\n",str);
fflush(stdout);
fp = fopen("tmp","r");
if (fp == NULL) return;
fgets(buf,MAX_LEN,fp);
// here, buf gets str's content
fclose(fp);
fclose(stdout);
return 0;
}
scanf(" %[^\n]", in);
then for example , i input Knock Knock and hit enter
but my code block inside
if (strcmp ("Knock Knock",out)==0)
does not work
please instruct me ,thanks a lot!
char in[80],out[80];
void input(){
printf("Client: ");
scanf("%[^\n]",in);
fp=fopen("test","w");
if (!fp) return ;
fputs(in,fp);
fclose(fp);
}
fp=fopen("test","r");
fgets(out,81,fp);
fclose(fp);
fp=fopen("test","w");
if (strcmp ("Knock Knock",out)==0)
fputs("Server: Who is there?\n",fp);
First off, the layout of the code is very confusing, and as it stands, it would never compile. You have a function input() that you never seem to call, and you leave code outside the function that should be inside another function, or better yet, all of it should be contained inside a main() function so that it can be executed. Here is a cleaned up example for what you're wanting to-do:
#include <stdio.h>
char in[80],out[80];
int main()
{
printf("Client: ");
scanf("%[^\n]",in); //you really should use fgets() here
FILE* fp = fopen("test.txt","w");
if (!fp)
{
perror("Failed to open file");
return 1;
}
fputs(in,fp);
fputs("\n",fp);
fclose(fp);
fp = fopen("test.txt","r");
if (!fp)
{
perror("Failed to open file");
return 1;
}
fgets(out,80,fp);
fclose(fp);
fp = fopen("test.txt","a+");
if (!fp)
{
perror("Failed to open file");
return 1;
}
if (strcmp ("Knock Knock\n",out)==0)
fputs("Server: Who is there?\n",fp);
return 0;
}
Some important notes:
1) fp has a file-type FILE*, since that is the return of fopen(), but you never declare it as such. So this would never compile with that error.
2) Every time you open a file with the w flag, it erases the entire contents of the file. So if you were intending on appending to the file to have a history of what your output from your program was, you need to use the a+ flag when calling fopen()
3) It would be nice to have some type of error print-out if you failed to open the file rather than scratching your head at why "test.txt" is empty after the program takes the input from stdin. Also if you're going to keep re-opening the file, check for a NULL each time since you're going to get unpredictable results from trying to work with a NULL file pointer (most likely a crash).
4) scanf() can result in nasty buffer over-runs from user-input (or malicious user input) ... use fgets() with stdin to a known-length buffer instead.
You should be able to compile this code now and run it. Works for me with gcc 4.4.3 on Ubuntu. After running, your "test.txt" file should look like:
Knock Knock
Server: Who is there?