0

so im new to c++ and i have a project that i am currently doing in school however im stuck on how to get an entire row of info from a user input selection.

here is what my txt file looks like

1 Home Work 5
2 Work Home 5
3 Home School 6
4 School Home 6
5 Work School 8
6 School Work 8

so basically if they input/ cin option 3 but how do i print and obtain the values in row 3 to display and compute later on?

heres my code

#include <iostream>
#include <iomanip>
#include <fstream>
#include <stdlib.h>
#include <string>
#include <cstdlib>
#include <Windows.h>
#include <cmath>

void bookingmenu();
void confirmedbooking(double calc);

double calc;
using namespace std;

int main()
{

    ifstream inFile;
    string PUP, Dropoff, others, otherstwo;
    double distance = 0, calc;
    string ON;
    int sel;
    char choice;

    inFile.open("blist.txt");

    if (!inFile)
        cout << "Error, unable to open text file.\n" << endl;

    else
        cout << left << fixed << setprecision(2);//how many dp
    cout << left << setw(25) << "Option Number" << left << setw(25) << "Pick Up Point" << "Dropoff Point" << endl; //display column header

    while (!inFile.eof())
    {
        inFile >> ON >> PUP >> Dropoff;
        if (inFile.fail()) break;
        cout << left << setw(25) << ON << left << setw(25) << PUP << Dropoff << endl;

    }

    cout << "Please select an option for your trip: ";
    cin >> sel;
    
    //(im stuck after here)
    
    cout << "You have selection option number " << ON << " and your pickup point is " << PUP << " and your dropoff point is " << Dropoff << endl;


    system("pause");
    return 0;

}
  • 1
    Can you add your output? And if the problem is to read a line from a file, have you tried `std::getline`? – Roy Avidan Aug 20 '20 at 17:48
  • See [Option Two in this linked answer](https://stackoverflow.com/a/7868998/4581301) for a good way to get started. – user4581301 Aug 20 '20 at 17:50
  • 1
    Also read [Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-i-e-while-stream-eof-cons) It will help you with a bug you likely haven't spotted yet. – user4581301 Aug 20 '20 at 17:51
  • Recommendation: Keep the definition of a variable close to where you use it. This allows you to better scope the variable so it's only around when you need it and is less likely to be holding some stale value that skews the results. Also when functions start getting complex, it's annoying to scroll around to find what `calc` really is. – user4581301 Aug 20 '20 at 17:57
  • calc is a return value. this is actually jus one of my user defined functions –  Aug 20 '20 at 17:59
  • My apologies, you've already solved the eof bug with the `break`, but you can do it more efficiently with `while (inFile >> ON >> PUP >> Dropoff)`. With this the loop won't even enter on any sort of error. No need for a second test. – user4581301 Aug 20 '20 at 18:00
  • i have a bigger main function but this is the only function i cant seem to sort out –  Aug 20 '20 at 18:00
  • I called out `calc` mostly because it exists twice: Once as a global and once as a local in `main` if `calc` was being used in this example, the global `calc` would be hidden by the local `calc` inside `main` and any other function counting on the global `calc` to be set buy `main` would get a value of unknown pedigree because the local one was set. – user4581301 Aug 20 '20 at 18:03
  • i tried getline but i cant really grasp how to make proper use of it too –  Aug 20 '20 at 18:04
  • my concern isnt calc now tho... –  Aug 20 '20 at 18:05
  • what i mean is right now, main isnt actually main. i copy pasted this from my bigger code to isolate the problem. so actually right now the main that u see is another function called bookingmenu() as u can see from the prototypes –  Aug 20 '20 at 18:06
  • Suggestion: Make a `struct` that contains `ON`, `PUP` and `Dropoff`. Read a line from the file into the `struct`. Put the `struct` into a `std::vector`. You can then read back out of the `vector` later when you need the data read from the file. – user4581301 Aug 20 '20 at 18:06
  • all i need is actually to COUT the data from the row that the user has input so to display what they have chose –  Aug 20 '20 at 18:12
  • The you need to do that first. Get the selection, find the line with the selection number in the file, print that one line. – user4581301 Aug 20 '20 at 18:17
  • Recommendation: Add that bit to the question. It's utterly vital information, and the question cannot be answered without it. Everything I've done up to now has been educated guesses at what you want. – user4581301 Aug 20 '20 at 18:18
  • That said, if you need to make multiple queries of the contents of the file, read the file into a data structure that makes the rows of the file easy to look up, and then perform the queries on the data structure. – user4581301 Aug 20 '20 at 18:21
  • You can open a shell script you create dynamically, which passes just the data you want, but it seems a lot simpler to just put the file into memory either by reading it up front into a data structure or mmap() it or read it each time you need it (these days input i/o often does an mmap(), so it is all in memory). http://www.cplusplus.com/reference/istream/istream/seekg/ – David G. Pickett Aug 20 '20 at 18:38

1 Answers1

0

Make a list of things you need to do:

  1. read file (almost done)
  2. print options in file (done)
  3. put data somewhere we can look it up later (not done)
  4. get option from user (done)
  5. look up option (not done)
  6. print selected option (almost done)

Fixing point 1

The current code reads three fields from the row of data. There are 4 fields. The fourth field needs to be removed from the stream.

int unused;
while (inFile >> ON >> PUP >> Dropoff >> unused) // read unused field into junk variable
{
    //print
}

Implementing point 3

Define a structure that can store the data

struct record
{
    string PUP;
    string Dropoff;
};

Option number will be likely used as the key for looking up the structure, so it doesn't need to be in the structure.

Next we need a container to store these records

If the file is guaranteed to be start with a predictable option number and be listed in a continuous sequential order, we can use a std::vector to store the records. If the list is predictable, sequentially ordered and of known size we can use std::array If not, use an associative table to map the option number to the record. We're not given any guarantees of ordering or size, so I'll demonstrate with std::map

record in;
map<int, record> records; // convenient data structure for look-up
int ON;
int unused; // need to read and dum that last field on the line
while (inFile >> ON >> in.PUP >> in.Dropoff >> unused)
{
    records[ON] = in; // store row in datastructure at the option number.
}

If you're smart, you will read the file and print the menu at the same time. Otherwise you're reading the file twice or unnecessary looping through the container of records.

Implementing point 5

Look up the record in the container. If std::map is used, that can be as simple as

record & out  = records.at(sel);

at will throw an exception if the option is not in the list. You can either catch and handle the exception or let the program crash.

Fixing point 6

We use the reference to the record to update the existing code to use the correct record.

user4581301
  • 33,082
  • 7
  • 33
  • 54