-4
int numFiles;
cout << "How many signal files are there?";
cin >> numFiles;

vector<string> signalFiles(numFiles);
vector<string> backgroundFiles(numFiles);

string backgroundFile;

for (int i=0;i<numFiles;i++){

    string singalFiles;
    cout << "Please input the name of singal file" << i << ".";
    cin >> singalFiles[i];
    signalFiles.push_back(signalFiles());

    string backgroundFiles;
    cout << "Please input the name of background file" << i << ".";
    cin >> backgroundFiles[i];
    backgroundFiles.push_back(backgroundFiles.str());

}

How would I go about using the push_back method for the given vectors?

I get the following error message in the code:

No member named 'str' in 'std::__1::basic_string<char>'

I am confused as to why I am receiving this message.

Eric Leschinski
  • 146,994
  • 96
  • 417
  • 335
Channing
  • 166
  • 1
  • 9
  • if this is actually your code, then you have a typo: you have `cin>>singalFiles[i];` instead of `cin>>signalFiles[i];` – FCo Feb 20 '15 at 21:52
  • 1
    Why do the string variables exist? You read directly into the vectors. The `push_back` lines don't seem to be accomplishing anything. You're making the code harder than it has to be: http://coliru.stacked-crooked.com/a/6b9e506b56e4e738 – chris Feb 20 '15 at 21:54
  • 2
    Why do you have string variables with almost the same name as vector ones? – juanchopanza Feb 20 '15 at 21:54
  • Wow... you're sure a fast reader. Learning C++ in 45 minutes is impossible, but even reading C++ Primer in such a short time is impressive... – 6502 Feb 20 '15 at 21:56
  • 1
    Oh, I see. You seem to be combining the two methods mentioned [here](http://stackoverflow.com/a/28637477/962089), but they both accomplish the same thing. Usually, you'll pick one of either reserving space in a vector and reading the elements directly (`std::cin >> signalFiles[i]`) or reading into a temporary variable and adding it to the vector (`std::string temp; std::cin >> temp; signalFiles.push_back(temp);`). Which one to use depends on whether you know how many to read beforehand. – chris Feb 20 '15 at 21:58
  • thank you Chris. that seemed to work. I just started C++ about 3 hours ago. appreciate it :) – Channing Feb 21 '15 at 00:34

1 Answers1

2

There are a few problems with your code:

  1. you are pre-allocating the size() of each std::vector, which means you are pre-filling them with blank values. Then you are reading into those existing elements (which is fine) and also push_back()ing what you have already stored (which is wrong). So, either stop pre-allocating the size() (you can use the reserve() method to pre-allocate the capacity() instead) so you can use push_back() correctly, or else use the vector [] operator to assign the existing elements and remove the push_back() altogether.

  2. Your backgroundFiles string variable is in conflict with your backgroundFiles vector variable (same name being used). You need to rename them so they are unique.

  3. std::string does not have str() or operator() members. You declared your std::vector containers to hold std::string elements, and the values you are reading from std::cin are already std::string types, so just store them as-is.

  4. You are using cin >> over and over without taking line breaks into account. That >> operator stops reading when it encounters whitespace, not when it encounters a line break. You should switch to std::getline() instead.

Try this instead:

int numFiles = 0;
cout << "Please input the number of signal files:";
if (!(cin >> numFiles)) {
    // error reading the number, do something
}
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');

vector<string> signalFiles, backgroundFiles;
signalFiles.reserve(numFiles);
backgroundFiles.reserve(numFiles);

for (int i = 0; i < numFiles; ++i) {

    string signalFile;
    cout << "Please input the name of signal file " << i+1 << ":";
    if (!getline(cin, signalFile)) {
        // error reading the string, do something
        break;
    }
    signalFiles.push_back(signalFile);

    string backgroundFile;
    cout << "Please input the name of background file " << i+1 << ":";
    if (!getline(cin, backgroundFile)) {
        // error reading the string, do something
        break;
    }
    backgroundFiles.push_back(backgroundFile);
}

Or this:

int numFiles = 0;
cout << "Please input the number of signal files:";
if (!(cin >> numFiles)) {
    // error reading the number, do something
}
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');

vector<string> signalFiles(numFiles);
vector<string> backgroundFiles(numFiles);

for (int i = 0; i < numFiles; ++i) {

    string signalFile;
    cout << "Please input the name of signal file " << i+1 << ":";
    if (!getline(cin, signalFile)) {
        // error reading the string, do something
        break;
    }
    signalFiles[i] = signalFile;

    string backgroundFile;
    cout << "Please input the name of background file " << i+1 << ":";
    if (!getline(cin, backgroundFile)) {
        // error reading the string, do something
        break;
    }
    backgroundFiles[i] = backgroundFile;
}

I prefer the first approach, as the vector size() will accurately reflect how many files were successfully read and pushed. With the second approach, if an error occurs, the vector size() will include the default blank values that were not overwritten.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770