Hey,

I have a program that it supposed to read two columns of data and then perform a calculation on them. The problem is reading the data in from the file. I have a function to count the lines, this works correctly. It returns it's value into a variable called lines.

The program then tries to read data from the file into some dynamically allocated memory. It then prints the results.

However sometimes the data read from the file is absolute junk.

The thing is that the data is never junk if i don't call the function "countlines" and just assign the variable lines the length of the dat file.

WIERD

#include <stdio.h>
#include <stdlib.h>

int countlines(FILE* fp)
{
    int lines;
    char c;
    lines=0;
    
     while(c!=EOF)
      {
          c=getc(fp);
          
          
          if(c=='\n')
             lines++;
             
      }

      return lines;

}


    

int main(int argc, char *argv[])
{
  FILE* fp;
  int lines,i;
  float* x;
  float* fx;
  
  lines=3;
  
  
  fp=fopen("a.dat","r");
  
  
  if(fp==NULL)
  {
      printf("Error opening file\n");
      getchar();
      return 0;
  }
  
 lines=countlines(fp);   ////HERE IS THE DEMON  if i don't call this
                                        //the program gives expected output
                                        ///otherwise junk e.g all 0 or really big
                                       //numbers
  
  
      
  fx =(float*)malloc(lines*sizeof(float));
    x=(float*)malloc(lines*sizeof(float));
      
  if( fx==NULL)
  {
      printf("Error allocating memory\n");
      getchar();
      return 0;
  }
  
  
  if( x==NULL)
  {
      printf("Error allocating memory\n");
      getchar();
      return 0;
  }
  
  for(i=0; i<lines; i++)
  fscanf(fp,"%f %f",&x[i],&fx[i]);
  
  
  for(i=0; i<lines; i++)
  printf("%f %f\n",x[i],fx[i]);
  
 
 
  
  
  
  
  free(x);
  free(fx);
  
  fclose(fp);
  
  getchar();
  return 0;
}

I would really appreciate someone telling what i am doing wrong

thanks very much

oh and i'm compiling under dev c++ configured as C only

getc returns an int; EOF is an int.

[edit]Also, you'll need to rewind fp the way you're doing things..

int countlines(FILE* fp)
{
   int c, lines = 0;
   while ( (c = getc(fp)) != EOF )
   {
      if ( c == '\n' )
         lines++;
   }
   rewind(fp);
   return lines;
}

Thanks for the speedy reply

I changed it to

int countlines(FILE* fp)
{
    int lines;
    int c;
    lines=0;
    
     while(c!=EOF)
      {
          c=getc(fp);
          
          
          if(c=='\n')
             lines++;
             
      }

      return lines;

}

It still give me junk :(.

I may have been pokey with my edit -- you'll need to rewind fp before you start trying to read the data.

Having a safety check like this...

for ( i = 0; i < lines; i++ )
   {
      if ( fscanf(fp, "%f %f", &x[i], &fx[i]) != 2 )
      {
         break;
      }
   }

...would have helped point you in that direction.

I may have been pokey with my edit -- you'll need to rewind fp before you start trying to read the data.

Having a safety check like this...

for ( i = 0; i < lines; i++ )
   {
      if ( fscanf(fp, "%f %f", &x[i], &fx[i]) != 2 )
      {
         break;
      }
   }

...would have helped point you in that direction.

Once again thanks for you speedy reply.

I tried your addition.

However it STILL gives junk data :(

Do you have any ideas why it might be doing this?

Thanks

Dunno.

#include <stdio.h>
#include <stdlib.h>

/**
 * A simple line-counter. (Has issues with special cases.)
 * @param file  pointer to a file stream
 * @return the number of lines in the file
 */
int countlines(FILE* file)
{
   int c, lines = 0;
   while ( (c = getc(file)) != EOF )
   {
      if ( c == '\n' )
         lines++;
   }
   rewind(file); /** Need to rewind to later begin reading at the beginning. */
   return lines;
}

int main(int argc, char *argv[])
{
   float *x, *fx;
   int i, j, lines = 3;
   static const char filename[] = "a.dat";
   /** Try to open the file for reading. */
   FILE* file = fopen("a.dat", "r");
   if ( file == NULL )
   {
      perror(filename);
      return 0;
   }
   /** Count the lines in the file and allocate memory accordingly. */
   lines = countlines(file);
   fx = malloc(lines * sizeof *fx);
   x  = malloc(lines * sizeof *x);
   if ( fx == NULL || x == NULL )
   {
      puts("Error allocating memory");
      return 0;
   }
   /** Attempt to read the data from the file. */
   for ( i = 0; i < lines; i++ )
   {
      if ( fscanf(file, "%f %f", &x[i], &fx[i]) != 2 )
      {
         break;
      }
   }
   /** Print the data from the file. */
   for ( j = 0; j < i; j++ )
   {
      printf("%f %f\n", x[j], fx[j]);
   }
   /** Cleanup and exit. */
   free(x);
   free(fx);
   return 0;
}

/* a.dat
1    4
3    9
5    14
7    19
9    24
*/

/* my output
1.000000 4.000000
3.000000 9.000000
5.000000 14.000000
7.000000 19.000000
9.000000 24.000000
*/

[edit]Did you catch that all-important bit about rewind?

commented: nice one Dave :D +1

Sorry Dave,

I am such a dumbass.

No i didn't catch the rewind bit.

Is this because the file pointer is at the end of the file and then i'm trying to fscanf after the end of file?

Massive thankyou

EDIT: why did you change this? I though you had to explicitly cast this? or does it not matter?

#
fx = malloc(lines * sizeof *fx);
#
x = malloc(lines * sizeof *x);

Once again thankyou

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.