0

I'm working on a segment of a program where I have to read doubles from a .dat file I created which holds 12 doubles which looks like:

10.0
20.0
30.0
40.0
50.0
60.0
70.0
80.0
90.0
100.0
110.0
120.0

Here is my code:

double readSales(FILE *input, double sales[])
{
    int count = 0, n;
    double s;
    n = fscanf(input, "%lf", &s);
    sales[0] = s;

    while(n == 1)
    {
    n = fscanf(input, "%lf", &s);
    count++;
    sales[count] = s;
    }
}

This works fine but I don't think it is well written due to having to declare the first element of the array. The issue is without the declaration, I just get a 0.0 as the first element of the array. Thank you for any feedback.

1
  • Welcome to StackOverflow! Be sure to take the tour and visit the help center. Could you post the code that exhibits the problem you mention? Then you could get help with fixing it. Commented Mar 16, 2019 at 18:28

2 Answers 2

1

You are writing to the array before checking if the input is valid. I suggest

int readSales(FILE *input, double sales[])      // change the type
{
    int count = 0;
    double s;
    while(fscanf(input, "%lf", &s) == 1) 
    {
        sales[count] = s;
        count++;
    }
    return count;                               // number of elements
}
Sign up to request clarification or add additional context in comments.

4 Comments

Maybe something like if(ferror(input)) return perror("input"), 0; at the end would signal an error.
Also, if the file has 13 doubles, this programme is going to crash -- I would check the count before assigning.
@NeilEdelman how do you know it would crash? OP has not shown the full code. Ideally it would be right to pass the maximum array length as an argument, but this answer addresses the basic question.
I assume that the user calls this with double[12] but you are right, there is no way to know. One may pass a pointer double (*const)[12] to turn on compile-time checks.
0

Here's my offer on one way to implement this. I've included a main().

#include <stdio.h>

size_t readSales( FILE *input, double sales[],
                  const size_t salesSize )
{
  if ( ! input || ! sales ) { return 0; }

  size_t numRead = 0;

  while ( numRead < salesSize &&
          fscanf( input, "%lf", sales++ ) ) numRead++;

  return numRead;
}

int main( int argc, char* argv[] )
{
  double d[12];
  FILE* fp = fopen( "sales.txt", "r" );

  if ( ! fp )
  {
    printf( "No sales.txt\n" );
    return 1;
  }

  size_t numRead = readSales( fp, d, sizeof d / sizeof( *d ) );

  for ( int i = 0; i < numRead; ++i )
  {
    printf( "%f\n", d[i] );
  }

  fclose( fp );

  return 0;
}

It's a good idea to include the size of your array as an argument to readSales() to avoid buffer overrun, so I've modified the readSales() signature as such.

Do input validation for safety.

This answer addresses what you stated as your main concern in your original question: i.e. avoiding initialization of the 0th element of the array. You are correct that it is unnecessary for the task.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.