-5

So I'm currently a second year computer engineering student and I've run into a massive wall with this C++ data structures class I'm currently enrolled in. This program I have to create should read data from a file, input that data into a vector and display the minimum and maximum for that file. She also wants me to use a template, but I'm just trying to get this thing off the ground before I traverse that road. Now the issue I'm having is I can't get anything going besides this point in my code.

Now this code is obviously incomplete, but I can't seem to figure out how to read these values into a vector and then throw the values that are strings. To be honest with you, I'm lost in the sauce and am, for lack of a better metaphor, throwing brown stuff against a wall and seeing if it sticks. I understand these topics individually, but combining them and throwing in a data file has me lost. If someone could take the time to sit down and help me work this out because my professor hasn't been answering my emails for a week (online only course) and this project is due on Tuesday and I've been working for the last 2 days and have NOTHING completed.

I'd greatly appreciate the assistance and understand I'm on the verge of losing it. I have no issues in my Java, Diff Eq or HTML/CSS course but this C++ course is absolutely dominating me (Received a B in the intro to C++ course). Thanks again and I appreciate anyone who can help!

//Nicholas Stafford
//COP2535.0M1 
//Read in text file into multiple vectors and display maximum and minimum integers/strings.

#include <iostream> 
#include <string>
#include <vector>
#include <fstream>
#include <algorithm>


using namespace std;



int main() {

    ifstream inputFile; //File input object
    const int fSize = 6;
    int numCt = 0; //Counts number of integers
    vector<int> numInt(fSize);
    string numWd;


    //Open input file
    inputFile.open("minmax.txt");

    //Data validation for file
    if (inputFile)
    {
        //Try method to remove string values
        try
        {
            //Only pull the integer values into a vector
            while (inputFile >> numInt)
            {
                numCt++;
            }
        }
        catch (string noString)
        {
            cout << noString;
        }

    }
}
NStafford
  • 11
  • 3
  • Try input to an integer, then adding the integer to the vector. There's no need to track the number of integers in the vector, the vector does that for you. – Nick Matteo Mar 06 '16 at 02:50
  • I would suggest finding a mentor / working with peers at school. This broad question (especially with additional unnecessary information) generally does not fare well on SO. – user2864740 Mar 06 '16 at 02:51
  • There is a very simple way to make it do what you want, if you know C++ and it's standard library well enough. But to help you with this problem at hand, you first need to learn the basics of inputting single values and how to append them, one by one, to a vector. – Some programmer dude Mar 06 '16 at 02:52
  • If she asked me to place user input I would have zero issues. 90 percent of my problem is I can't seem to find a clear example that shows a input file being fed into a vector. – NStafford Mar 06 '16 at 02:55
  • Do you know how to read a single value from a stream (any stream, doesn't have to be a file, and remember that `std::cin` is a stream)? Do you know how to add a single value to a vector? Then you already have all the knowledge you need. – Some programmer dude Mar 06 '16 at 02:57
  • Also, you don't need the `numCt` variable. Once the input is done the size of the vector will be the number of integers you have read. – Some programmer dude Mar 06 '16 at 02:59
  • 1
    @NStafford "*I can't seem to find a clear example that shows a input file being fed into a vector*" -- What do you see here? `std::vector v; int x; cin >> x; v.push_back(x);` -- I see an input stream (`cin`) placing one item into a vector. So how would you expand on this to input multiple items? Doesn't it sound like some sort of *loop* over that `cin - push_back` code? – PaulMcKenzie Mar 06 '16 at 03:01
  • I was utilizing the file reading that I understand from a couple sections ago and tried mashing it with the new vector content. It's obvious that I need to read some more on what a vector does for me. – NStafford Mar 06 '16 at 03:04
  • std::vector v; int x; cin >> x; v.push_back(x); This may make sense to me. But I would just replace this int as a data file input? – NStafford Mar 06 '16 at 03:07
  • @NStafford - Say "input **stream**", not "input file". In C++, the good thing is that if you know how to use `cin`, then using `ifstream` objects are practically the same thing. – PaulMcKenzie Mar 06 '16 at 03:07
  • So does the name of my ifstream (inputFile in my case) kind of replace what would be a cin? So if I wanted to add to this vector, push_back would be what I use in conjuction with the ifstream? – NStafford Mar 06 '16 at 03:13
  • Furthermore, if I use a loop, would I just feed the input into a variable that goes inside of the vector with push_back? – NStafford Mar 06 '16 at 03:15
  • @NStafford -- The short answer is "Yes". C++ is not as disjointed as you think it is w.r.t. input-output. http://en.cppreference.com/w/cpp/io/basic_istream `cin` and `ifstream` inherit from the same class. You can take code that uses `cin` and for the most part, replace all of your `cin` with an `ifstream` object, and the code will work. – PaulMcKenzie Mar 06 '16 at 03:15
  • "On the verge of a breakdown" may describe your mental state, but it does not describe your problem to anyone scanning the list of questions. – Jonathan Potter Mar 06 '16 at 03:20
  • Okay, I'll move forward with this information and maybe start smaller with just feeding one integer from the file into a vector. Maybe I bit too much of the apple at one time. – NStafford Mar 06 '16 at 03:26
  • Just wanted to say thanks again, correlating the cin with ifstream made it click. Thanks again. – NStafford Mar 06 '16 at 03:45

1 Answers1

1

You mentioned that you have background in Java, and I regret to inform you that you're suffering from Java-itis:

    try
    {
        //Only pull the integer values into a vector
        while (inputFile >> numInt)
        {
            numCt++;
        }
    }
    catch (string noString)
    {
        cout << noString;
    }

This would be more or less how these kinds of things work in Java: if an error occurs, Java typically throws an exception. Here, you are attempting to read an int value, and you are assuming that an exception gets thrown if the next item read is not an integer.

That's how it typically works in Java, but that's not how C++ works.

If the >> operator fails, C++ sets the input stream to an error status, and return normally without performing the conversion, leaving the int value uninitialized. C++ does not throw an exception. C++ code, in general, throws far fewer exceptions than equivalent Java code.

Adding insult to injury, as I've said several times before, I think that beginners in C++ unfairly experience a lot of frustration, due to no fault of their own, with the >> operator on input streams. Their instructors teach them to use it all the time, but they really shouldn't. This is a textbook example why.

You are expecting that >> reads the next line of text. It doesn't. It reads the next whitespace-delimited glob from the input stream. If you have

2  3

then the >> operator will only read '2', and not '3'. Furthermore, the >> operator treats newlines just like any form of whitespace. And, as I mentioned, because of the way that >> handles error reporting, you explicitly have to check for it.

In conclusion, this how you should be handling each line of input, in C++:

std::string line;

std::getline(std::cin, line);

This reads a single line of text. That's it. Only after you've completed that step, you can start messing around with the >> operator, to figure out what's in there:

std::istringstream parse(line);

parse >> numInt;

if (parse.fail())
{
     // Conversion failed, to what you want with it.
}

Clean, and simple, and a parsing failure here won't affect the status of the std::cin input stream, which you'd otherwise be obligated to reset, upon a failure.

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148
  • Okay, I see now. the getline() operator would be the proper way in C++. I'll restructure the program and go from there. Thanks for the help – NStafford Mar 06 '16 at 03:02
  • 1
    **By default** it won't throw exceptions, but it's easy to make it throw by setting the [exceptions](http://www.cplusplus.com/reference/ios/ios/exceptions/) flag. – Clément Mar 06 '16 at 03:06
  • I see from what you wrote. So I should be explicitly doing these exceptions in C++ rather than leaning on the way the language operates? – NStafford Mar 06 '16 at 03:09
  • I would not recommend enabling exceptions. – Sam Varshavchik Mar 06 '16 at 03:14