Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 5 years ago.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Improve this question
Please, some one can explain for me why this program does not work ?
I'm trying to read and write from the file by using r+. The file test.txt exists and the writing is executed correctly. However, the reading does not work.
int main() {
FILE* fichier = NULL;
int age, TAILLE_MAX=10;
char chaine[TAILLE_MAX];
fichier = fopen("test.txt", "r+");
if (fichier != NULL)
{
printf("give your age ? ");
scanf("%d", &age);
fprintf(fichier, "Hello you have %d year old", age);
while (fgets(chaine, TAILLE_MAX, fichier) != NULL)
{
printf("%s", chaine); //does not print
}fclose(fichier);
}
return 0;
}
By does not work I mean it does not display any thing ! Even if the file contains some the sentence you have ... year old. There is no Error. Just the program does not print the content of the file
you are writing and reading to file at the same time,
which is not good practice,
but the reason your code does not work is because of buffering. The fprintf(fichier, "Hello you have %d year old", age); is likely not happening until your fclose(fichier) statement is happening.
I added the two statements to your code, see below.
Also once you do your fprintf your file pointer fichier is not at the end of the file which is the wrong place for the next thing you try to do which is read the age number you just wrote, so you have to move the file pointer fichier back somehow - I just used rewind which will work if test.txt was a newly created file. Otherwise you will need some method of moving the file pointer fichier backwards just enough to read what you just wrote.
int main() {
FILE* fichier = NULL;
int age, TAILLE_MAX=10;
char chaine[TAILLE_MAX];
fichier = fopen("test.txt", "r+");
if (fichier != NULL)
{
printf("give your age ? ");
scanf("%d", &age);
fprintf(fichier, "Hello you have %d year old", age);
fflush( fichier ); /* force write to FILE */
rewind( fichier ); /* rewind FILE pointer to beginning */
while (fgets(chaine, TAILLE_MAX, fichier) != NULL)
{
printf("%s", chaine); //does not print
}
}
fclose(fichier);
return 0;
}
in your original code, the statement
while (fgets(chaine, TAILLE_MAX, fichier) != NULL)
fails to read anything and returns NULL, so the printf("%s", chaine); will not happen. This is happening because of output buffering and the fprintf() statement not happening when you think it should.
This output buffering is normal and if you want a printf to happen at that exact moment then you need to use fflush()
read here to learn more: Why does printf not flush after the call unless a newline is in the format string?
The problem is you try to read from the filehandle after you've written to it.
fichier is like a cursor in an editor, and it only ever has one position in the file. When you open the file with r+ fichier is at the beginning of the file. When you print to fichier it overwrites whatever was at the beginning of the file. Then when you try to read, it reads from where the print left off.
For example, if I start test.txt with some text in it, specifically more than will be printed.
$ cat test.txt
First line
Second line
Third line
Then I run the program.
$ ./test
give your age ? 41
rd line
Notice it printed rd line because that's what's left over after it writes Hello you have 41 year old.
$ cat test.txt
Hello you have 41 year oldrd line
I'm not sure what you're trying to accomplish, but you probably need to fseek to move the cursor to the correct position.
As a side note, wrapping the whole program in if (fichier != NULL) is awkward. And you have no error message if the file does not open, it will quietly and mysteriously do nothing. Instead, check for an error, display an informative message, and exit the program.
#include <string.h>
#include <errno.h>
#include <stdlib.h>
char file[] = "test.txt";
FILE *fichier = fopen(file, "r+");
if (fichier == NULL) {
fprintf(stderr, "Could not open '%s' for r+: %s\n", file, strerror(errno));
exit(1);
}
This is known as early exit and makes code much, much simpler. By taking care of errors immediately, the code can follow a happy path without always needing to be nested in a conditional.
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed last month.
Improve this question
I need help with this code. You see, it is taking inputs likes strings and integers and saves them in two arrays . Those two should be written into a file with the name "Lagerverwaltung.text". However it just prints a 0 and nothing else into the file.
Thank you.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
char artnr[50],menge[50],me[50],neu[50],date[50];
int zahl, calcam, id, sub,amount;
int greatlen = 0;
int result = 0;
char str[50][50][50];
int mengen[10];
int a = 1;
int s = 0;
while(a > 0){
FILE* fp;
fp = fopen("Lagerverwaltung.txt", "w");
printf("Geben sie eine Zahl ein:");
scanf("%d", &zahl);
if(zahl == 1){
printf("Geben sie ein:\nArtikelnr.:");
scanf("%s",&artnr);
strcpy(str[s][0],artnr);
printf("Menge:");
scanf("%d",&mengen[greatlen]);
printf("Mengeneinheit:");
scanf("%s",&me);
strcpy(str[s][1],me);
printf("Datum:");
scanf("%s",&date);
strcpy(str[s][2],date);
}
fputs(str[greatlen][0], fp);
fprintf(fp, "%d", mengen[greatlen]);
fputs(str[greatlen][1], fp);
fputs(str[greatlen][2],fp);
fclose(fp);
s =s+1;
greatlen = greatlen +1;
}
return 0;
}
There should be a line of integers and strings written into a file.
fopen with "w" parameter opens the file and discards existing content. That means that in each loop iteration you discard whatever you have written previously. Since a never goes to 0, the only option to end the program is to abort it, and you'll be doing that while it waits for input, which is after it has already discarded any file content but before it has written new content.
Possible fixes:
open the file with "a" to append to it
open the file before the loop and close it after the loop (while providing a way to exit the loop).
Also, fix the string-scanning lines like
scanf("%s",&artnr);
that should be
scanf("%s", artnr);
and every decent compiler would warn you about it.
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
I am writing a program that reads a string and writes that string in another file which has not been created.
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{
char s[50];
FILE *fp;
fp = fopen("E:\\poem.txt","w");
if(fp = NULL)
{
printf("Cannot open file");
exit(1);
}
printf("Enter a string\n");
while(strlen(gets(s))>0)
{
fputs(s,fp);
fputs("\n",fp);
}
fclose(fp);
return 0;
}
Since the "w" mode creates a new file if file is not already created,my program creates that file however it is unable to write it to the file
The double slash in fp = fopen("E:\\poem.txt","w"); is because i thought \p cannot be a escape sequence but i want to go to the directory E:\ so i used double slash.
However I even tried fp = fopen("poem.txt","w"); same thing happen creates a file but doesnot write on it.
Also checked this question but was not helpful C: can't write data on file
From man page of gets():
gets() returns s on success, and NULL on error or when end of file
occurs while no characters have been read.
When gets() return NULL (on failure), then strlen(NULL) causes segmentation fault.
So, you can simply use while(gets(s)!=NULL) instead of while(strlen(gets(s)) > 0)
As you mentioned in comment a typo use== instead of =
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
char s[50];
FILE *fp;
fp = fopen("E:\\poem.txt", "w");
if (fp == NULL)
{
printf("Cannot open file");
exit(1);
}
printf("Enter a string\n");
while (strlen(gets(s)) > 0)
{
fputs(s, fp);
fputs("\n", fp);
}
fclose(fp);
return 0;
}
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
I want to read file with C program here is the code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE * fptr;
fptr = fopen("text.txt","r");
char arr[150];
char c;
int i;
while(!feof(fptr) && i<5)
{
printf("%d\n",i++);
fgets(arr,150,fptr);
puts(arr);
}
fclose(fptr);
return 0;
}
When executed the program wont stop and the characters printed are weird, i dont know what is going wrong ?
The part causing error in your program is :
while(!feof(fptr))
Better read : What is wrong with "while(!feof(fptr))" and Why it's bad to use feof() to control a loop
A simple program to read is below which checks if file is opened or not. It's a good practice to check if file you are to perform operations on is opened or not.
#include <stdio.h>
#include <stdlib.h>
int main()
{
char ch;
FILE *fp;
fp = fopen("text.txt", "r"); // read mode
if (fp == NULL) //Checking if file is open
{
perror("Error while opening the file.\n");
exit(EXIT_FAILURE);
}
printf("The contents of %s file are:\n", file_name);
while((ch = fgetc(fp)) != EOF){
printf("%c", ch); //Avoided creating a buffer
}
fclose(fp);
return 0;
}
#Though not so much realevant!!
I think the easiest way to read/write from/to file is using freopen() function. You can use scanf() & printf() in case of C and cin & cout in case C++ to read or write from file with this function.
Read from file: freopen("input.txt","r",stdin); where input.txt is filename.
Write to file: freopen("output.txt","w",stdout); no need to create output.txt your own. The file is automatically created when the program is executed.
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 4 years ago.
Improve this question
I'm trying to use the fseek() and ftell() function to find the length of the file 'test.txt' which is present in the same directory as the file 'file.c'.
file.c
#include <stdio.h>
int main()
{
FILE *fp;
int len;
fp = fopen("test.txt", "r");
if(fp == NULL)
printf("Error opening file.");
fseek(fp, 0, SEEK_END);
len = ftell(fp);
fclose(fp);
printf("The size of the file test.txt is: %d.\n", len);
return 0;
}
test.txt
abc def
There is no problem when I compile the file, but when I try to run it, I'm getting the 'Segmentation fault (core dumped)' error and the execution terminates.
I'm trying to run this on a standard user in the Ubuntu environment.
You may be wondering why you did not see the printf statement before the 'Segmentation fault' occurred.
This is due to stream buffering of stdout. You either have fflush(stdout) or print a newline "\n" to prevent the output from being buffered.
In this case, 'Segmentation fault' has occurred before the buffer is flushed and printed.
So you can try either this:
printf("Error opening file.");
fflush(stdout);
or this:
printf("Error opening file.\n");
And of course, do not do anything more with the file pointer if it is NULL.
Actually, you'll better use perror(3) instead of printf for such error handling (if you insist on printf, show somehow the errno(3), perhaps as strerror(errno); see also strerror(3)). So we suggest:
if(fp == NULL) {
perror ("fopen test.txt");
exit (EXIT_FAILURE);
}
You don't need super user permission here. You are trying to open a file in read only mode. If the file is not existing then fopen() fails. Even if the file is not present you are trying to get the length of the file.
So you can try this:
#include <stdio.h>
int main()
{
FILE *fp;
int len;
fp = fopen("test.txt", "r");
if(fp == NULL){
printf("Error opening file.\n");
}else{
fseek(fp, 0, SEEK_END);
len = ftell(fp);
fclose(fp);
printf("The size of the file test.txt is: %d.\n", len);
}
return 0;
}
The problem with your code is probably test.txt is missing on the specified location and you are trying to open it. Even though open fails you are trying to get the length of the file which causes segmentation fault.
You don't need to open the file to check the length, and doing so increases the risk of failure because of lacking permission, etc.
If you want to check the length of a file (rather than figure out how fseek and ftell are working) I would suggest the following:
struct _stat buffer;
if (_stat("test.txt", &buffer) != 0) {
// stat failed, does file exist? Access?
}
else {
printf("Length of file %s is %i\n", "test.txt", buffer.st_size);
}
Note that I tested the syntax on Windows, and on Ubuntu, you might need to drop the underscore in front of stat.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 5 years ago.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Improve this question
I have designed a program in c program to count the number of rows but it shows the garbage values.
My file contains the data as follows
2,8,10
3,5,7
4,5,1
3,6,8
3,7,8
3,8,4
for counting the number of rows i have written the program as
int count_lines =0;
char sample_char;
FILE *fptr;
fptr = fopen("demo3.txt", "r");
sample_chr = getc(fptr);
while (sample_chr != EOF)
{
if (sample_chr == '\n')
count_lines = count_lines +1;
sample_chr = getc(fptr);
}
printf("\n\n\n The number of lines are %d",count_lines);
but the garbage values are being printed here. Where i am going wrong???
when i am writing the below code it works perfectly
typedef struct ratings {
int userId;
int movieId;
int rating;
}Ratings;
int i, n=65;
FILE *fptr;
fptr = fopen("demo3.txt", "r");
/* *//counting the number of lines present in the above file
sample_chr = getc(fptr);
while (sample_chr != EOF)
{
if (sample_chr == '\n')
count_lines = count_lines +1;
sample_chr = getc(fptr);
}* */
printf("\n\n\n The number of lines are %d",count_lines);
//storing the values in array of structures
for(i=0;i<n;i++)
fscanf(fptr, "%d,%d,%d", &REC1[i].userId, &REC1[i].movieId, &REC1[i].rating);
now if i am printing the contents i am getting the output. If i remove the comment lines then garbage value appears
You forgot to check whether the file opened.
fptr = fopen("demo3.txt", "r");
Every file operation, especially opening a file, should be error checked. Here's an example.
#include <stdio.h>
#include <string.h>
#inculde <errno.h>
...
char filename[] = "demo3.txt";
FILE *fptr = fopen(filename, "r");
if( fptr == NULL ) {
fprintf( stderr, "Could not open %s for reading: %s\n",
filename, strerror(errno)
);
exit(1);
}
//storing the values in array of structures
for(i=0;i<n;i++)
fscanf(fptr, "%d,%d,%d", &REC1[i].userId, &REC1[i].movieId, &REC1[i].rating);
This would be what is producing the garbage. Because it comes after getc is done reading the file, calls to fscanf will try to read past the end of the file and fail (again, check every file operation). Nothing will be put into REC1, it will contain the garbage it had when it was declared.
Think of fptr like a cursor in an editor. Every time you read from it, the cursor moves forward. Every call to getc moves the cursor forward one character. By the time you call fscanf, it's reached the end of the file.
You can move the cursor around with fseek. Use it to move fptr back to the beginning of the file. And, yup, check to make sure it worked.
if( fseek(fptr, 0, SEEK_SET) != 0 ) {
fprintf( stderr, "Could not rewind %s: %s\n", filename, strerror(errno) );
}
Note that you'll still get garbage because you're reading n times rather than count_lines times.
Note that you can't display the offending line. This, and many other reasons, is why it's best to avoid fscanf and instead read the line with fgets and use sscanf to parse the line. This also does away with the need to read n times, just read until all the lines are done.
// A line buffer
char line[1024];
int i = 0;
// Read a line
while( fgets( line, sizeof(line), fptr) != NULL ) {
// Parse the line
if( sscanf(line, "%d,%d,%d", &REC1[i].userId, &REC1[i].movieId, &REC1[i].rating) < 3 ) {
fprintf( stderr, "Could not understand '%s' from %s\n", line, filename );
continue;
}
// Print what we got
printf("uid: %d, mid: %d, rating: %d\n", REC1[i].userId, REC1[i].movieId, REC1[i].rating);
i++;
}
As for making sure REC1 is big enough to hold all the lines, look into realloc.
after walking through the file, counting the number of lines,
Then need to rewind() or lseek() the file back to the beginning before extracting the data