fscanf always returns 0(CLOSED) - c

I am a beginner in C programming, and I am trying to write a simple code to read a text file and write its content into an array, then print it on console. However, I always get 0.0000, and I could not solve the problem.
#include <stdio.h>
#include <stdlib.h>
int numOfLines(FILE *fp1);
void printarr(float arr[], int size);
float *filetoArr(FILE *fp, int arrsize);
int main(int argc, const char *argv[]) {
char *fileName1 = argv[1];
FILE *fp1 = fopen(fileName1, "r");
printf("File name: %s", fileName1);
int size = numOfLines(fp1);
printf("Number of lines in the file: %d\n", size);
float *arr = filetoArr(fp1, size);
printarr(arr, size);
free(arr);
fclose(fp1);
}
void printarr(float *arr, int size) {
for (int i = 0; i < size; i++) {
printf("%f ", *(arr + i));
}
}
float *filetoArr(FILE *fp, int arrsize) {
int size = arrsize;
float *arr = (float *)malloc(sizeof(float) * size);
for (int i = 0; i < size; i++) {
fscanf(fp, "%f\n", (arr+i));
}
return (arr);
}
int numOfLines(FILE *fp1) {
int numberOfLines = 0;
char c;
do {
c = getc(fp1);
if (c == '\n') {
numberOfLines++;
}
} while (c != EOF);
return numberOfLines;
}

your numOfLines goes to the end of the file.
You have to rewind(fp1) to reset your file handle to position 0, or fscanf hits the end of the file, and doesn't read anything (check return code from fscanf: it should be 1 I bet you're getting 0 all the time)

There are multiple problems in your code:
you read the whole file in numOfLines(): you must reset the file pointer to the beginning of file with rewind(fp1); so fscanf() can read the file instead of hitting the end of file immediately.
the variable c used to read bytes from the file must be defined as an int for the test for end of file to be reliable. Otherwise, depending on whether char is signed or not by default, the EOF would never match or could potentially match the character \377 as end of file erroneously.
you do not check for failure to open the file.
Although returning 0 is implicit for function main() since C99, it is advisable to write the return 0; statement explicitly for better clarity.

Related

Struct fscanf in file C

In file I need to read some inputs:
this is an example:
8 15
[1,1] v=5 s=4#o
[4,2] v=1 s=9#x
typedef struct{
int red2;
int stupac2;
int visina;
int sirina;
char boja[10];
}Tunel;
FILE* fin = fopen("farbanje.txt", "r");
Tunel* tuneli = malloc(sizeof(Tunel)*50);
// if(fin!=0)
fscanf(fin,"%d %d", &r,&s);
printf("%d %d", r,s);
int p=0;
while (fscanf(fin, "[%d,%d]", &tuneli[p].red2, &tuneli[p].stupac2) == 2)
{
p++;
}
for(i=0;i<p;i++)
{
printf("[%d,%d]", tuneli[i].red2, tuneli[i].stupac2);
}
Problem is that it wont read me properly inputs from here: [1,1] v=5 s=4#o
Last line where i use printf shows some random numbers.
Agree it is better to use fgets
But if you want to continue to use your current approach,
#include <stdio.h>
#include <stdlib.h>
typedef struct{
int red2;
int stupac2;
int visina;
int sirina;
char boja[10];
}Tunel;
int main(){
int r, s, i;
FILE*fin=fopen("farbanje.txt", "r");
if(fin==NULL) {
printf("error reading file\n");
return 1;
}
Tunel *tuneli=(Tunel*)malloc(sizeof(Tunel)*50);
fscanf(fin,"%d %d\n", &r,&s);
printf("%d %d", r,s);
int p=0;
while (fscanf(fin, " [%d,%d]%*[^\n]", &tuneli[p].red2, &tuneli[p].stupac2) == 2)
{
p++;
}
fclose(fin);
for(i=0;i<p;i++)
{
printf("[%d,%d]", tuneli[i].red2, tuneli[i].stupac2);
}
}
Last line where i use printf shows some random numbers....
The random numbers you see are because the buffers to print were not properly populated yet.
This example shows how to read the file, using fgets() to read a line buffer, then use sscanf() to parse the first two values from the lines. (read in-code comments for a few other tips.)
int main(void)//minimum signature for main includes 'void'
{
int r = 0;
int s = 0;
char line[80] = {0};//{initializer for arrays}
int p = 0;
Tunel *tuneli = malloc(sizeof(*tuneli)*50);
if(tuneli)//always test return of malloc before using it
{
FILE *fin = fopen(".\\farbanje.txt", "r");
if(fin)//always test return of fopen before using it
{
fgets(line, sizeof(line), fin);
sscanf(line, "%d %d", &r, &s);
while(fgets(line, sizeof(line), fin))
{
sscanf(line, " [%d,%d]", &tuneli[p].red2, &tuneli[p].stupac2);
//note space ^ here to read only visible characters
printf("[%d,%d]\n", tuneli[p].red2, tuneli[p].stupac2);//content is now populated corretly
p++;
}
fclose(fin);//close when finished
}
free(tuneli);//free when done to prevent memory leaks
}
return 0;
}

Error while using malloc and FILE pointer together

So, what I am trying to do is initialize an unsigned integer buffer and also using a file pointer(FILE *fp) to read from a file and store the contents of the file in the above mentioned buffer
The thing is that the problem doesn't occur when I don't use malloc() and define the buffer as an unsigned integer array instead
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 10000
void main()
{
unsigned int i = 0;
unsigned int *buffer = (unsigned int*)malloc(sizeof(unsigned int)*SIZE);
unsigned int c;
unsigned int length = 0;
FILE *fp = fopen("testfn.c", "r");
if (fp == NULL) {
printf("\nFile not found.\nExiting...");
exit(1);
}
while ((c = fgetc(fp)) != EOF)
{
buffer[i] = c;
++i;
}
length = i;
printf("\nNumber of elements= %d\n", length);
for (i = 0; i <= length; ++i)
printf("%c ", buffer[i]);
fclose(fp);
}
The expected output are the contents of the file stored as integers and printed on the screen.
What I am receiving is a segmentation fault and no output.

Confusing yet interesting C behavior while counting size of file

I am writing a very simple C program to count the size of a file. I have a success in counting both text,.odt, and binary files. However, after I made some minor changes in the code I get a different result for .odt and binary files.
This is my code that gives correct results:
while(fgetc(pFile)!=EOF) size++;
And this is the one that gives me different and wrong results for binary and odt files (and I can't understand why it is different?)
size=0;
c=fgetc(pFile);
while(c!=EOF)
{
c=fgetc(pFile);
size++;
}
Note: This code gives correct results for text files though.
This is the overall code (function) :
int count(char * file)
{
int size;
char c;
FILE * pFile;
size=0;
c=' ';
pFile = fopen(file, "rb");
if(!pFile)
{
printf("Invalid file(%s)!\n",file);
exit(EXIT_SUCCESS);
}
c=fgetc(pFile);
while(c!=EOF)
{
c=fgetc(pFile);
size++;
}
// while(fgetc(pFile)!=EOF) size++;
fclose(pFile);
return size;
}
I'm pretty sure it was the declaration of c. Here is some sample code which works.
#include <stdio.h>
#include <errno.h>
int fsize(char *s)
{
FILE *pF = NULL;
int c = 0; /* declaring this as char will bring you funny results */
int iSize = 0;
pF = fopen(s, "r");
if (! pF)
{
perror("Cannot open file");
return -1;
}
fseek(pF, 0, SEEK_SET);
while(EOF != (c = fgetc(pF)))
iSize ++;
fclose(pF);
return iSize;
}
int main(int argc, char **argv)
{
int i;
for(i = 1; argc > i; i ++)
printf("%10d %s\n", fsize(argv[i]), argv[i]);
return 0;
}
I am not sure what do you mean by " count the size of a file".
But if you want the file size,
Following code will do I hope.
#include <sys/stat.h>
struct stat sbuf;
stat(filepath, &sbuf);
printf("%jd\n", (intmax_t)sbuf.st_size);
I believe you are getting the file size a little lesser than the actual size.
The reason i believe causing that is the c=fgetc(pFile); being written twice. One outside while and one inside. The control executes the first c=fgetc(pFile);, goes into while and again inside while executes c=fgetc(pFile); without incrementing size.
size=0;
c=fgetc(pFile);
if(c!=EOF)
{
size++;
}
while(c!=EOF)
{
c=fgetc(pFile);
size++;
}
Here, if the file is empty fgetc will return a EOF. So we increment only if c is returned with a value other than EOF.
This should fix that. Hope this helped.

C Program double free or corruption error

Currently working on a concordance program in C. When I try to run the program though, I get an error.
This is my C program:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
void print(char Table, int n) {
printf("%d: ", n+1); // Prints the table
}
int insert(const void *bb, const void *cc) {
return strcmp(*(const char **)bb, *(const char **)cc);
}
void empty(char *Table[]) {
strcat(Table,"NULL"); // Empties the table
}
int main(int argc, char *argv[]){
if(argc!=3){
printf("ERROR: Usage: concordance table_size"); // Errors due to not enough variables (Should be tablesize and file name)
} else {
FILE *fp; //This block opens the file user has inputted and makes the string "File_contents" set to the file's contecnts
fp = fopen(argv[2],"r");
char *file_contents;
long input_file_size;
fseek(fp, 0, SEEK_END);
input_file_size = ftell(fp);
rewind(fp);
file_contents = malloc((input_file_size + 1) * (sizeof(char)));
fread(file_contents, sizeof(char), input_file_size, fp);
fclose(fp);
file_contents[input_file_size] = 0;
char *word, *words[strlen(file_contents)/2+1];
int i, n;
for(i=0;file_contents[i];i++){
file_contents[i]=tolower(file_contents[i]); //Converts all words to lower case
}
i=0;
word = strtok(file_contents, " ,.-:;?!"); //Chars which signal end of word
while(word != NULL) {
words[i++] = word;
word = strtok(NULL, " ,.-:;?!");
}
n = i;
qsort(words, n, sizeof(*words), insert);
for(i=0; i<n; ++i){
print(words[i],i);
printf("%s\n", words[i]);
}
empty(words);
fclose(fp); // Closes open file
}
return 0;
}
And the following is the error I'm getting:
* glibc detected * concordance: double free or corruption (!prev): 0x0000000001060f010
Not sure what could be causing this error to happen. Any help on this would be great though.
You aren't calling fclose() twice. Which I suppose in turn might call free() internally. Remove the fclose() at the end of the program.
you are passing NULL as argument to strtok function. I think this may cause the problem

Read comma separated numbers from a file in C

I have a problem when trying to read a file with comma separated numbers, I want to have a function that creates arrays of integers (not knowing how many parameters the array has at first) in a file like this:
1,0,3,4,5,2
3,4,2,7,4,10
1,3,0,0,1,2
and so on. The result I want is something like
int v[]={1,0,3,4,5,2}
for every line in the file (obviously with the values in each line) so I can add this array to a matrix. I tried using fscanf, but I can't seem to make it stop at the end of each line. I also tried fgets, strtok, and many other suggestions I found on the Internet, but I don't know how to do it!
I'm using Eclipse Indigo in a 32-bit machine.
#include <stdio.h>
#include <stdlib.h>
int main(){
FILE *fp;
int data,row,col,c,count,inc;
int *array, capacity=10;
char ch;
array=(int*)malloc(sizeof(int)*capacity);
fp=fopen("data.csv","r");
row=col=c=count=0;
while(EOF!=(inc=fscanf(fp,"%d%c", &data, &ch)) && inc == 2){
++c;//COLUMN count
if(capacity==count)
array=(int*)realloc(array, sizeof(int)*(capacity*=2));
array[count++] = data;
if(ch == '\n'){
++row;
if(col == 0){
col = c;
} else if(col != c){
fprintf(stderr, "format error of different Column of Row at %d\n", row);
goto exit;
}
c = 0;
} else if(ch != ','){
fprintf(stderr, "format error of different separator(%c) of Row at %d \n", ch, row);
goto exit;
}
}
{ //check print
int i,j;
// int (*matrix)[col]=array;
for(i=0;i<row;++i){
for(j=0;j<col;++j)
printf("%d ", array[i*col + j]);//matrix[i][j]
printf("\n");
}
}
exit:
fclose(fp);
free(array);
return 0;
}
With the following code you will store the CSV into a multidimensional array :
/* Preprocessor directives */
#include <stdio.h>
#include <stdlib.h>
#define ARRAYSIZE(x) (sizeof(x)/sizeof(*(x)))
const char filename[] = "file.csv";
/*
* Open the file.
*/
FILE *file = fopen(filename, "r");
if ( file )
{
int array[10][10];
size_t i, j, k;
char buffer[BUFSIZ], *ptr;
/*
* Read each line from the file.
*/
for ( i = 0; fgets(buffer, sizeof buffer, file); ++i )
{
/*
* Parse the comma-separated values from each line into 'array'.
*/
for ( j = 0, ptr = buffer; j < ARRAYSIZE(*array); ++j, ++ptr )
{
array[i][j] = (int)strtol(ptr, &ptr, 10);
}
}
fclose(file);

Resources