Getting segmentation fault while from a file using fscanf in c - c

int main() {
FILE *matrix_r;
matrix_r=fopen("matrix.txt","r");
double x;char c;
while(feof(matrix_r)){
fscanf(matrix_r,"%lf%c",&x,&c);
printf("%lf%c",x,c);
}
fclose(matrix_r);
return 0;
}
Trying to read float values from the file but getting segmentation fault core dumped error. matrix.txt stores a matrix of floats.
contents of matrix.txt are below.
0.000000,876.671546,448.879717,1349.827396
876.671546,0.000000,1319.195209,964.193445
448.879717,1319.195209,0.000000,1741.628261
1349.827396,964.193445,1741.628261,0.000000

fopen() failed and feof(NULL) caused the segfault. If fopen() was successful then feof() would return false and the loop wouldn't run but your program wouldn't segfault.
Check the return value of fopen() & fscanf(). You only need to call feof() if you need to find out why fscanf() failed to read 2 items.
#include <stdio.h>
int main() {
FILE *matrix_r = fopen("matrix.txt", "r");
if(!matrix_r) {
perror("fopen");
return 1;
}
for(;;) {
double x;
char c;
int rv = fscanf(matrix_r, "%lf%c", &x, &c);
if(rv != 2)
break;
printf("%lf%c", x, c);
}
fclose(matrix_r);
}
Here is the output:
0.000000,876.671546,448.879717,1349.827396
876.671546,0.000000,1319.195209,964.193445
448.879717,1319.195209,0.000000,1741.628261
1349.827396,964.193445,1741.628261,0.000000

You do not check if fopen was successful. Calls to feof or fscanf if the file pointer is NULL invoke Undefined Behaviour
while(feof(matrix_r)){
while(!feof(...))) is always wrong (Why is “while( !feof(file) )” always wrong?), but your one has no logical sense at all (as you want to scanf if it is the end of the file).

Related

getting undefined behavior in counting characters of text file program?

I wrote a c program meant to count the characters in a certain file.
int main(void) {
FILE *fp;
fp = fopen("txt.txt", "r");
char text;
int count;
while (fscanf(fp, "%c", &text) != EOF) {
count++;
}
printf("%d", count);
return 0;
}
I want to add a char array into it but for some reason it changes the value of my int type (count).
for example, if I run this program I get an output of 3549. Now, lets say I declare "char potato[5000]" alongside my other char type. For some reason I get a completely different output of 159062601. Why is this and how do I prevent that?
The following proposed code:
initializes variables before using them (your compiler should have told you about this problem.
properly checks and handles I/O errors for fopen() and for fscanf()
properly closes the open file before exiting. I.E. it cleans up after itself
properly terminates printed text, so it is immediately passed to the terminal
and now, the proposed code:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
FILE *fp;
fp = fopen("txt.txt", "r");
if( ! fp )
{
perror( "fopen failed" );
exit( EXIT_FAILURE );
}
char text;
int count = 0;
while ( fscanf( fp, "%c", &text ) == 1 )
{
count++;
}
fclose( fp );
printf( "%d\n", count );
return 0;
}
You have several problems in your code. i will list them below:
In c programming we declare variables in the scope begin. and initialize them if we need so. you have a mixture of declerations and code.
count variable non initialized!! you have entered the while loop with garbage value in count. UB (Undefined behavior) - in each run you will get different values.
you didnt check the return value of fopen !! you must check if the operating system succed in opening the file you have requested to manipulate.
regarding asking a question in stackoverflow, your code is not complete and you didnt post all of it.
Now lets try to learn new topics regarding working with IO streams.
return value of function fscanf
The value EOF is returned if the end of input is reached before
either the first successful conversion or a matching failure occurs.
EOF is also returned if a read error occurs, in which case the
error indicator for the stream (see ferror(3)) is set, and errno
is set indicate the error.
This is how check if errors ocured while working with the file we are reading:
int ferror(FILE *stream);
The function ferror() tests the error indicator for the stream pointed
to by stream, returning nonzero if it is set. The error indicator can
only be reset by the clearerr() function.
And in this function bellow we get a human readble error, not just an errnor number!
explain_ferror
const char *explain_ferror(FILE *fp);
The explain_ferror function is used to obtain an explanation of an
error returned by the ferror(3) system call. The least the message
will contain is the value of strerror(errno), but usually it will do
much better, and indicate the underlying cause in more detail.
The errno global variable will be used to obtain the error value to be
decoded.
#include <stdlib.h>
#include <stdio.h>
#include <libexplain/ferror.h> /* for the non standard const char* explain_ferror(FILE* fp); */
int main(void)
{
FILE *fp;
char text;
int count = 0;
fp = fopen("txt.txt", "r");
if(fp == NULL)
{
perror("fopen failed"); /*write to standard error*/
exit(EXIT_FAILURE);
}
while (fscanf(fp, "%c", &text) != EOF)
{
++count;
}
if (ferror(fp)) /* nonzero return if error occured */
{
fprintf(stderr, "%s\n", explain_ferror(fp));
exit(EXIT_FAILURE);
}
printf("%d", count);
return 0;
}
Since the const char *explain_ferror(FILE *fp); is not GNU standard function, i am posting a GNU standard functions in the code snippet below:
char *strerror(int errnum);
strerror is standard library c function which returns a pointer to a string that describes the error code passed in the argument errnum. Be aware that this function is not Thread safe. for thread safe function use The strerror_r().
Return Value
The strerror(), function return the appropriate error description string, or an "Unknown error nnn" message if the error number is unknown.
Since POSIX.1-2001 and POSIX.1-2008 requires that a successful call to strerror() shall leave errno unchanged, and note that, since no function return value is reserved to indicate an error, if we wishe to check for errors we should initialize errno to zero before the call (by calling void clearerr(FILE *stream);, and then check errno after the call.
#include <string.h>
#include <errno.h>
#include <stdio.h>
...
clearerr(fp); /* clear previous seted errno */
while (fscanf(fp, "%c", &text) != EOF)
{
++count;
}
if (ferror(fp)) /* nonzero return if error occured */
{
fprintf(stderr, "%s\n", strerror(errno));
exit(EXIT_FAILURE);
}
...
Finally:
man pages (or man7) or typing man <enter_string_here> in terminal on linux shall clear all the q.marks.
for further reading go to:
explain_ferror
ferror
fscanf

Segmentation fault SIGSEGV error on BeagleBone

I have still problem with a Segmentation fault in the C code. When I call the function current_live_read(ainpath); for the 8th time I'm getting the error: No source available for "_int_malloc() at 0x25be2"
The main function looks like this:
void current_read(void)
{
system(AINinit);
char *ainpath;
ainpath=init_current();
int *current;
float avgcurr=0;
float allcurr=0;
int i=0;
while(1)
{
//sleep(1);
i++;
current=current_live_read(ainpath);
allcurr=allcurr+*current;
avgcurr=allcurr/i;
printf("\n Current: %d AVG: %f", *current, avgcurr);
//free(current);
}
}
The current_live_read(ainpath); is like that:
int *current_live_read(char *ainpath)
{
//ainpath=init_current();
int curr;
FILE *file = fopen(ainpath, "r");
//free(ainpath);
if(!file)
{
printf("Error opening file: %s\n", strerror(errno));
}
else
{
fscanf(file, "%4d", curr);
fclose(file);
//*current=curr;
}
free(file);
return curr;
}
I know that something could be wrong with the pointers, but I don't know which one and what I can do about it.
You may not free the FILE * pointer after closing it. From the manpage:
Flushes a stream, and then closes the file associated with that stream. Afterwards, the function releases any buffers associated with the stream. To flush means that unwritten buffered data is written to the file, and unread buffered data is discarded.
So fclose() already does the cleaning up as needed to prevent a memory leak. If you call free() on that pointer, you are likely to corrupt your heap. So just remove the free(file);
Furthermore, you have to pass a pointer to fscanf() like this:
fscanf(file, "%4d", &curr);
Otherwise you write to a (pseudo)random memory address. It is usually a good idea to check the return value of fscanf() to see, if the conversion succeeded and handle the error case approriately.
This should eliminate the problem.
So I changed the int *current_live_read(char *ainpath); to int current_live_read(char *ainpath) without pointer type.
Make inside function:
int curr; fscanf(file, "%x", &curr)
And in main function the current is just integer:
int current;

C - Using fscanf to read '-1' from a file

I'm a bit new to C, but basically I have a problem where I need to read '-1' from a file. Sadly this means I run into a premature ending of the file, because the EOF constant is also -1 in my compiler.
What sort of work arounds would there be for this? Is there another function I can use to read it that will change the EOF to something I can work with?
Thanks in advance.
The code since people are asking for it
int read() {
int returnVal; // The value which we return
// Open the file if it isn't already opened
if (file == NULL) {
file = fopen(filename, "r");
}
// Read the number from the file
fscanf(file, "%i", &returnVal);
// Return this number
return returnVal;
}
This number is then later compared to EOF.
Okay this is probably bad practice, but I changed the code to the following
int readValue() {
int returnVal; // The value which we return
// Open the file if it isn't already opened
if (file == NULL) {
file = fopen(filename, "r");
}
// Read the number from the file
fscanf(file, "%i", &returnVal);
if (feof(file)) {
fclose(file);
return -1000;
}
// Return this number
return returnVal;
}
Because I knew I would never read any such number from my file (they range from about [-300, 300]. Thanks for all your help guys!
The return value of fscanf is NOT the value that was read, but rather it is the number of items successfully read, or EOF if an error occurred.
The problem is that your read function doesn't distinguish between a successful read and an error condition. You should change it to accept a int * as a parameter that scanf writes into, and the function should return something like 0 on a successful read and -1 on error. You can use the return value of scanf as the basis of what your function returns.
Also, there's a system call named read, so you should really name it something else. And don't forget to fclose(file) at the end of the function, otherwise you're leaking file descriptors.

fopen() causing segfault before it's called

I am having a very weird error, I would try to run valgrind, but I am on OS X Yosemite, so this is not possible. I am getting a segfault with an fopen, it seems before the fopen is ever even called. I have a function called format:
void format(uint16_t sector_size, uint16_t cluster_size, uint16_t disk_size)
{
FILE *fp;
fp=fopen(diskName, "wb");
if(fp != NULL)
{
printf("Disk successfully initialized at: %s",diskName);
}
else
{
printf("There was an error creating the disk.");
return;
}
for(int i=0;i<disk_size;i++)
{
fwrite(0, sizeof(sector_size), cluster_size, fp);
}
}
Diskname is declared globally at the top of the file:
char diskName[32];
Here is my main:
int main(int argc, char *argv[]) {
strcpy(diskName, "test.bin");
printf("%s",diskName);
format(128, 8, 1000);
}
The weird part is that, this code segfaults before it ever prints the diskname:
Run Command: line 1: 16016 Segmentation fault: 11
I have no idea how this is possible, and I've tried a wide-array of solutions, but it all boils down to an error with fopen. When fopen is commented out the code runs. Any idea why this would happen?
printf will buffer its output until you flush the output. This can be done by either printing a newline, or flushing the output using fflush(stdout).
In any case, your error is here:
fwrite(0, sizeof(sector_size), cluster_size, fp);
You may not see your program crash when you comment out the fopen call because the fwrite call will fail earlier. fwrite's signature expects a pointer to the data to write as the first argument, where you have provided zero. This will cause fwrite to attempt to dereference a NULL pointer and thus crash.
You can either allocate a buffer, set it all to zero, then write that to the file using fwrite, e.g.
char* buf = calloc(cluster_size, sector_size); // Remember, calloc initialises all elements to zero!
fwrite(buf, sector_size, cluster_size, fp);
Or just call fputc in a loop
for(int i = 0; i < sector_size * cluster_size; i++)
fputc(0, fp);
Also, sizeof(sector_size) will always return 2 in your example, as you're taking the size of the type. Are you sure this is correct?

compiler says:cannot convert int to FILE*

While doing filing im stuck here.The condition of the while loop is not working.The compiler says cannot convert int to FILE*.
while(pFile!=EOF);
Should i typecase the pFile to int?I tried that but it did not worked.Thanks in advance.
The complete code is:
int main()
{
char ch;
char name[20];
FILE *pFile;
int score;
pFile=fopen("database.txt","r");
if(pFile!=NULL)
{
while(pFile!=EOF);
{
fscanf(pFile,"%c",ch);
}
}
else
printf("Cant open the file.......");
fclose(pFile);
return 0;
}
First, you do not want to use while (!feof(pFile)) -- ever! Doing so will almost inevitably lead to an error where the last data you read from the file appears to be read twice. It's possible to make it work correctly, but only by adding another check in the middle of the loop to exit when EOF is reached -- in which case, the loop condition itself will never be used (i.e., the other check is the one that will actually do the job of exiting the loop).
What you normally do want to do is check for EOF as you read the data. Different functions indicate EOF in different ways. fgets signals failure (including EOF) by returning NULL. Most others (getc, fgetc, etc.) do return EOF, so you typically end up with something like this:
int ch; // Note, this should be int, NOT char
while (EOF != (ch=getc(pFile)))
process(ch);
or:
char buffer[MAX_LINE_SIZE];
while (fgets(buffer, sizeof(buffer), pFile))
process(buffer);
With scanf, checking for success is a little more complex -- it returns the number of successful conversions, so you want to make sure that matches what you expected. For example:
while (1 == fscanf(fPfile, "%d", &input_number))
process(input_number);
In this case I've used 1 because I specified 1 conversion in the format string. It's also possible, however, for conversion to fail for reasons other than EOF, so if this failes, you'll frequently want to check feof(pFile). If it returns false, do something like reading the remainder of the line, showing it to the user in a warning message, and then continuing to read the rest of the file.
It depends what pFile and EOF are defined as, but I will asssume that pFile is a *FILE, and EOF is from stdio.h. Then I guess you should do something like:
#include <stdlib.h>
#include <stdio.h>
#define FILENAME "file.txt"
int main(void) {
FILE *pFile;
int ch;
pFile = fopen(FILENAME,"r");
if (pFile) {
while ((ch = getc(pFile)) != EOF) {
printf("Read one character: %c\n", ch);
}
close(pFile);
return EXIT_SUCCESS;
} else {
printf("Unable to open file: '%s'\n", FILENAME);
return EXIT_FAILURE;
}
}
which yields
$ echo "abc" > file.txt
$ /tmp/fileread
Read one character: a
Read one character: b
Read one character: c
Read one character:
# last character being a linefeed
Assuming pFile is your file handle, this doesn't change as you read from the file. EOF is returned by e.g. fgetc(). See e.g. http://www.drpaulcarter.com/cs/common-c-errors.php#4.2 for common ways to solve this.
here is correct way:
c = getc(pFile);
while (c != EOF) {
/* Echo the file to stdout */
putchar(c);
c = getc(pFile);
}
if (feof(pFile))
puts("End of file was reached.");
else if (ferror(pFile))
puts("There was an error reading from the stream.");
else
/*NOTREACHED*/
puts("getc() failed in a non-conforming way.");
fclose(pFile);
pFile is a pointer to a file. EOF is usually defined as -1, a signed integer.
What you should do is fopen, make sure pFile != NULL, then call some function on the file handle until that function returns EOF. A pointer will (or rather, should) never be EOF. But a function acting on that pointer may return EOF.
I'm guessing you want to keep looping while you haven't hit end-of-file. In that case, you are looking for this:
while (!feof(pFile))
{
...
}
That said, this is still not quite correct. feof will only return true once it tries to read beyond the end of the file. This means feof can return false and yet there is no more data to read. You should really try your operation and only check for end of file if it fails:
char buffer[SIZE];
while (fgets(buffer, sizeof(buffer), pFile))
{
...
}
if (!feof(pFile))
{
// fgets failed for some reason *other* then end-of-file
}

Resources