0

I just started learning C++ and am trying to learn how to use scanf and printf for faster input and output. Here is the code I'm currently working on:

#include <stdio.h>
using namespace std;

int main() {
    int time, record;
    double down, loan;
    while (scanf("%d %lf %lf %d", &time, &down, &loan, &record) != EOF) {
        double value = down + loan;
        double owed = loan;
        double payment = owed/time;

        // current simulated month and depreciation
        int rday, c = 0;
        double temp, dep;
        bool found = false;

        // finds value and owed after records
        while (!found && record > 0) {
            scanf("%d %lf", &rday, &temp);
            // adjusts value and owed to day before listed on record
            while (!found && c <= rday) {
                if (c == rday) {
                    dep = temp;
                }
                value *= 1 - dep;
                if (c > 0) {
                    owed -= payment;
                }
                c++;

                // determines if found date
                if  (owed < value) {
                    found = true;
                }
            }
            record--;
        }

        // finds point where owed < value
        while (!found && value < owed) {
            value *= 1 - dep;
            owed -= payment;
            c++;
        }

        if (c - 1 == 1) {
            printf("%d month\n", c - 1);
        }
        else {
            printf("%d months\n", c - 1);
        }
    }
    return 0;
}

When I run this on Code::Blocks, it prints the correct answers, but the outermost while loop doesn't terminate even when I enter CTRL+Z (I am using Windows). Here is my input:

30 500.0 15000.0 3
0 .10
1 .03
3 .002
12 500.0 9999.99 2
0 .05
2 .1
60 2400.0 30000.0 3
0 .2
1 .05
12 .025
-99 0 17000 1

Here is an image of the what happens:

Error

I've tried changing the loop condition to scanf("%d %lf %lf %d", &time, &down, &loan, &record) == 4, but the same problem happens. Could someone please explain what the issue with my code is?

oso
  • 1
  • 2
  • 3
    ".. learning C++ and am trying to learn how to use scanf and printf for faster" --> consider learning about streams `<<` and `>>`. Save `scanf` and `printf` for C. – chux - Reinstate Monica Aug 21 '18 at 19:36
  • 1
    Why does code not check the return value of `scanf("%d %lf", &rday, &temp);`? I suspect this is the source of the "outermost while loop doesn't terminate" as the inner never finished. Either that or you are not signaling _end-of-file_ correctly. – chux - Reinstate Monica Aug 21 '18 at 19:37
  • Pressing "enter" after "ctrl+z" works? `Ctrl+z` just adds `EOF` to stdin, but `scanf` only process when `enter`is pressed. – Ripi2 Aug 21 '18 at 20:03
  • How was it determined that code is not stuck in `while (!found && value < owed)`? – chux - Reinstate Monica Aug 21 '18 at 20:05
  • @chux The input is formatted so that each line with four numbers represents a test case, and each line with two numbers is information used in the calculation. I'm also pretty sure `CTRL+Z` signals EOF. It's worked previously for other programs. – oso Aug 21 '18 at 20:09
  • @Ripi2 I pressed enter after `CTRL+Z` – oso Aug 21 '18 at 20:10
  • 1
    nitpick: instead of '#include ' use '#include ' See https://stackoverflow.com/questions/10460250/cstdio-stdio-h-namespace – Christopher Pisz Aug 21 '18 at 20:50

3 Answers3

2

In the line

while (scanf("%d %lf %lf %d", &time, &down, &loan, &record) != EOF)

you expect 4 variables to be read into when the read is successful. When scanf is able to successfully extract the data from stdin for all the arguments, it will return 4. Change the check to use that number.

while (scanf("%d %lf %lf %d", &time, &down, &loan, &record) == 4)
R Sahu
  • 204,454
  • 14
  • 159
  • 270
0

It's because scanf never returns EOF, so the termination condition is never satisfied.

CiaPan
  • 9,381
  • 2
  • 21
  • 35
  • @CiaPan: Thanks for the reply. Could you clarify what you mean when you say that `scanf` never returns EOF? I checked the documentation on www.cplusplus.com and it says "If a reading error happens or the end-of-file is reached while reading, the proper indicator is set (feof or ferror). And, if either happens before any data could be successfully read, EOF is returned." – oso Aug 21 '18 at 19:44
  • From https://en.cppreference.com/w/c/io/fscanf: *or EOF if input failure occurs before the first receiving argument was assigned.* – R Sahu Aug 21 '18 at 19:47
  • @RSAHU So I understand you already know the reason: there was some runtime constraint violation, right? – CiaPan Aug 21 '18 at 19:47
  • @CiaPan, the first comment was incorrect. They apply to `scanf_s` family of functions. The new comment applies to `scanf` family of functions. – R Sahu Aug 21 '18 at 19:48
0

Thanks for the suggestions and answers, everyone! I figured out the bug. Kind of embarrassing, but it turns out the issue was with the last line of input.

oso
  • 1
  • 2