Search code examples
c++vectorpush-back

How to use push back method for a C++ vector


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.


Solution

  • 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.