-1

what is wrong with my code? When given the following input (through file):

6.02
110 223 144 208 199.5 890
200 69.5 300 138.7 190 601

it prints ERROR: invalid price in airline # 1 while it should not do so. Here is a look at my code.

int fillPricesTable(double flightsPrices[][DEST],int n,double* dollarRate)
{
    //n is the number of rows
    double Price;
    int  AirLinesCounter=0;
    while (scanf("%lf",dollarRate)==EOF || *dollarRate<=0)
    {
        errorDollar();
        fflush(stdin);
    }
    for (int i=0;i<n;++i)
    {
        for (int j=0;j<6;++j)
        {
            if (scanf("%lf",&Price)==EOF || Price<=0)
            {
                printf("ERROR: invalid price in airline # %d\n", i);
                return -1;
            }
            flightsPrices[i][j]=Price;
        }
        AirLinesCounter++;
        if(scanf("%lf",&Price)==EOF)
            break;
    }
    return AirLinesCounter;
}
Sander De Dycker
  • 15,403
  • 1
  • 31
  • 37
Daniel98
  • 39
  • 5
  • 1
    What is `n` ? Please create a [minimal, reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) and update your question with it. – Sander De Dycker Jan 02 '20 at 14:27
  • Note the semantics of [Using `fflush(stdin)`](https://stackoverflow.com/q/2979209/15168) — it is not portable at minimum. – Jonathan Leffler Jan 02 '20 at 14:30
  • Flushing on stdin is undefined – Ed Heal Jan 02 '20 at 14:45
  • Not the actual problem you are asking about, but general tip: `scanf` can also return 0. Check the docs to see what this means. Consider what your code does in case `scanf` indeed returns 0. – hyde Jan 02 '20 at 14:50
  • @hyde Updated my code as suggested but still same bug – Daniel98 Jan 02 '20 at 17:05
  • Can you then show us how `fillPricesTable()` is called? How could anyone tell you why that error message is shown if that printf is not even include in the code section? – Roberto Caboni Jan 02 '20 at 19:59
  • I've rolled back your edit, since you removed vital information (specifically the error message that you're trying to figure out). The rest of the edit also served no purpose in clarifying the question (it changed the error handling based on a comment, and removed a comment). – Sander De Dycker Jan 03 '20 at 07:51

1 Answers1

2

Because of the if(scanf("%lf",&Price)==EOF) after the body of the for (int j=0;j<6;++j) loop (the one after AirLinesCounter++) you scan for one number too many in each loop on i.

Just remove the second if with the body.

The fflush(stdin); is technically undefined behavior. To read buffered data from input, loop getchar() until a newline or EOF.

You could for example remove the second if and for example add a condition in the error to handle the error of scanning the first number in the row separately:

int fillPricesTable(double flightsPrices[][DEST], int n, double *dollarRate)
{
    while (scanf("%lf", dollarRate) != 1 || *dollarRate <= 0) {
        errorDollar();
        for (int i; (i = getchar()) != '\n' && i != EOF;);
    }

    bool end_me = false;
    int i = 0;
    for (i = 0; i < n && end_me == false; ++i) {
        for (int j = 0; j < 6; ++j) {
            // no need to scan into temporary variable
            // just scan into the destination
            if (scanf("%lf", &flightsPrices[i][j]) != 1 || flightsPrices[i][j] <= 0)  {
                if (j == 0) {
                    // this is first number in the row
                    end_me = true; // using separate variable to end the outer loop
                    // because C does not have "break 2" or similar.
                    break;
                } else {
                    errorPrice(i);
                    return -1;
                }
            }
        }
    }
    return i; // AirLinesCounter is equal to i....
}
KamilCuk
  • 69,546
  • 5
  • 27
  • 60
  • But the second if should be entered only at the end of the file because it gets excited only after reading all 6 values at a line – Daniel98 Jan 02 '20 at 14:37
  • @Daniel98 — end of line is not the same as end of file. The inner loop terminates after reading 6 values (or if EOF is encountered earlier). – Jonathan Leffler Jan 02 '20 at 14:38
  • I'm seeing the same thing. For the input example shown and a value of 2 for n, your input value "200" is getting thrown away and making it only see 5 of 6 values for the second row. – Bob Shaffer Jan 02 '20 at 15:05
  • @BobShaffer I have updated my code could you take a look on what's wrong with my code it should literally work 100% I don't see any bug now! – Daniel98 Jan 02 '20 at 17:02
  • Remove the `if(scanf("%lf",&Price)==EOF) break;`... You are executing __7__ scanf calls for each `for (i=0;i – KamilCuk Jan 03 '20 at 00:11
  • If it was me, I'd probably read the input line by line into a buffer and use strtok and strtod to get the values. But, if you're wanting to use scanf for whatever reason, and you want to simplify things some, you can probably use feof(stdin) to check for EOF in your conditional and eliminate the end_me stuff. is it working like you have it then? – Bob Shaffer Jan 03 '20 at 23:08