-1

I've been having trouble figuring this out for a while now. I keep having issues with my if/else if statements. In my program, I'm trying to loop a list of customer for a telemarketer to read off of and record the call information into another document. I'm only having two issues that I believe are relatively small and minor but I can't figure it out with my google fu.

Here's my code:

#include <iostream>
#include <fstream>
#include <cstdlib>

using namespace std;

int main()
{
    char stat, answ;
    float rate;
    string fname, lname, phone, address;
    ifstream potentials("C:\\Users\\Brandon\\Desktop\\C++Projects\\Lab6\\potentials.txt");
    ofstream results("C:\\Users\\Brandon\\Desktop\\C++Projects\\lab6\\results.txt");

    if (!potentials) {
        cerr << "Unable to open file";
        exit(1);
    }

    while (!potentials.eof())
    {
        potentials >> stat >> fname >> lname >> phone;

        if (stat == 'X')
        {
            cout << "customer is preferred\n";
            rate = .079;
        }

        if (stat != 'X')
        {
            cout << "Customer is not preferred\n";
            rate = .129;
        }

        cout << fname << " " << lname << " " << phone << " " << rate << endl;
        cout << "Is this customer interested in this card? Y or N" << endl;
        cin >> answ;

        if (answ == 'Y')
        {
            cout << "Thank the customer and ask for their current address.\n";
            cin >> address;
            cout << "Thank the customer for accepting the offer, to expect a card in the mail soon, and happy charging!\n";
            results << fname << " " << lname << " " << stat << " " << address << " \r " << endl;
        }

        if (answ == 'N')
        {
            if (stat == 'X')
            {
                cout << "Tempt them with the cash back rewards and to call 18003838383 for a better offer.\n";
                results << fname << " " << lname << " " << answ << " " << address << " \r" << endl;
            }


            else if (stat != 'X');
            {
                cout << "Tell them thank you anyhow and to have a nice day.\n";
                results << fname << " " << lname << " " << answ << " " <<
                    address << " \r" << endl;
            }
        }
    }
}

Problem number 1:

For the address portion, I keep getting an error where if I include a normal address such as 123 w main st. That type of address will weirdly complete the loop. Like [so][1]. I don't know and understand why that happens. It will compile and execute just fine if I just put a number.

Problem number 2:

If the customer proceeds to call and decline the card, both the if statement and the else if statement will execute:

customer is preferred
Joe SCholz 437-4798 0.079
Is this customer interested in this card? Y or N
Y
Thank the customer and ask for their current address.
123 W Main St
Thank the customer for accepting the offer, to expect a card in the mail soon, and happy charging!
Customer is not preferredTim Wade 768-7658 0.129
Is this customer interested in this card? Y or N
customer is preferredSara JObs 326-7857 0.079
Is this customer interested in this card? Y or N
Customer is not preferredJaynce Bee 354-8678 0.0129
Is this customer interested in this card? Y or N

I don't understand this part either because the if statement should execute. If the customer doesn't have an X on their status in the file, then it should automatically go to the else if statement. Instead it executes both the if and the else if statement and I can't seem to figure out as to why that happens.

These are the only two things holding me back and I can't figure out both of them.

Swordfish
  • 12,971
  • 3
  • 21
  • 43
J. Doe
  • 11
  • 3
  • 3
    You do, hopefully, understand that using the `>>` overload on a `std::istream` and a `std::string` reads a ***single whitespace delimited word*** into the `std::string`, so if the input contains "123 w main street", at this point, all you'll get into your `std::string` is a sad, lonely, "123", with the rest of the input unread. Your obvious intent is to read the whole thing into the `std::string`, but that's not how `>>` works, and your C++ book should have a full explanation of how to use `>>`. See your C++ book for more information. – Sam Varshavchik Feb 25 '19 at 00:53
  • 4
    You can use `cout` statements in your code to see what values your variables contain. If you assume that they contain the values you want, you will spend a lot of time chasing phantom bugs. – Beta Feb 25 '19 at 00:55
  • 2
    [Why is iostream::eof inside a loop condition considered wrong?](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong) Also please define/declare variables as close to the position they're used/needed as possible and avoid (= don't) use `exit()` in C++. – Swordfish Feb 25 '19 at 00:57
  • 1
    Seems like your if/else concern would be alleviated by removing the semicolon which follows your if statement: else if (stat != 'X'); – Gardener Feb 25 '19 at 01:07

1 Answers1

0

The semicolon after the if statement was creating a problem. Also, the if/else logic did not carefully exclude and handle all possible answer choices. Finally, I used std::getline() for the read from std::cin which works better when you expect multiple words of input to a read from cin.

#include <iostream>
#include <fstream>
#include <cstdlib>

int main()
{
    char stat, answ;
    float rate;
    std::string fname, lname, phone, address, partial_address;
    std::ifstream potentials("C:\\Users\\Brandon\\Desktop\\C++Projects\\Lab6\\potentials.txt");
    std::ofstream results("C:\\Users\\Brandon\\Desktop\\C++Projects\\lab6\\results.txt");

    if (!potentials) {
        std::cerr << "Unable to open file ";
        return 1;
    }

    while ( true)
    {
        // This 'if' statement removes the while(!potentials.eof()) which created an extra read error
        // There are other ways to handle this, but this was a quick solution.  The read itself will return
        // a false value, but as we are trying to read 4 variables, this was one way of doing it.
        if(!(potentials >> stat &&
        potentials >> fname &&
        potentials >> lname &&
        potentials >>  phone)) {
            std::cout << "End of file." << std::endl;
            return -1;
        }

        // if you get into the habit of putting the constant on the left side of an equality,
        // you won't accidentally confuse '=' with '=='
        if ( 'X' == stat)
        {
            std::cout << "customer is preferred\n";
            rate = .079;
        } else if('Y' == stat) {  // I usually only check for the value you are looking for, but this is OK, if you create the catch-all else at the end.
            std::cout << "Customer is not preferred\n";
            rate = .129;
        } else {
            std::cout << "File corrupted.  First word in each line must be 'Y' or 'X'" << std::endl;
            return -1;  // exit the program as the file is corrupted
        }

        std::cout << fname << " " << lname << " " << phone << " " << rate << std::endl;
        std::cout << "Is this customer interested in this card? Y or N" << std::endl;
        std::cin >> answ;


        if ('Y' == answ || 'y' == answ)  // Just has to check for lower case as well  You can chuck that if you like
        {
            std::cin.ignore(); // cin has a tendency to skip the next input based on a prior "return" or "enter".  Gobble the new line
            std::cout << "Thank the customer and ask for their current address.\n";
            std::getline(std::cin, address);
            std::cout << "Thank the customer for accepting the offer, to expect a card in the mail soon, and happy charging!\n";
            results << fname << " " << lname << " " << stat << " " << address << " \r " << std::endl;
        } else if('N' == answ || 'n' == answ) {
            // AT this point, we already know that stat is either 'Y' or 'N', so we don't check explicitly on the else
            if ('X' == stat)
            {
                std::cout << "Tempt them with the cash back rewards and to call 18003838383 for a better offer.\n";
                results << fname << " " << lname << " " << answ << " " << address << " \r" << std::endl;
            } else {
                std::cout << "Tell them thank you anyhow and to have a nice day.\n";
                results << fname << " " << lname << " " << answ << " " <<
                        address << " \r" << std::endl;
            }
        } else {  // catch all else.  Not my preferred way to do this, but follows your design.
            std::cout << "Invalid response.  Response must be 'Y' or 'X'" << std::endl;
            return -1;  // exit the program as the response was not corrupted
        }
    }
}
Nimantha
  • 6,405
  • 6
  • 28
  • 69
Gardener
  • 2,591
  • 1
  • 13
  • 22