0

I need to parse a string into variables with varying data types (ints, strings).

The string in question was taken from a line in a file.

I'm wondering if there is a function similar to inFile >> var1 >> var2 >> etc; that I can use for a string. Below is the full line from the file.

2016/12/6 s "The incestuous relationship between government and big business thrives in the dark. ~Jack Anderson [4]" 0 3 39 blue white PATRICK BARDWELL pat.bardwell@bwpmlp.com

I have already assigned "2016/12/6," "s," and everything between the quotation marks to variables using inFile >> ;. Also, I took everything after the final occurrence of a double quote and stored that into the string restOfLine. Now, I'd like to parse restOfLine into variables for each value (0, 3, 39, blue, white, Patrick, Bardwell, pat.bardwell@bwpmlp.com should all be separate variables). Is there a method like inFile >> that I can use to do this? I also tried separating them with restOfline.find() and restOfLine.substr() but haven't been able to figure it out. Similarly, if I can separate each value from the entire line more efficiently than my current code, I'd prefer that. Current code below. Any help is much appreciated.

int main()
{

    // Declare variables
    string userFile;
    string line;
    string date;
    char printMethod;
    string message;
    int numMedium;
    int numLarge;
    int numXL;
    string shirtColor;
    string inkColor;
    string firstName;
    string lastName;
    string customerEmail;
    string firstLine;
    string restOfLine;


    // Prompt user to 'upload' file

    cout << "Please input the name of your file:\n";
    cin >> userFile;
    fstream inFile;
    inFile.open(userFile.c_str());

    // Check if file open successful -- if so, process

    if (inFile.is_open())
    {
        getline(inFile, firstLine); // get column headings out of the way
        cout << firstLine << endl << endl;

        while(inFile.good()) 
// while we are not at the end of the file, process
        {

            getline(inFile, line);

            inFile >> date >> printMethod; // assigns first two values of line to date and printMethod, respectively

            int pos1 = line.find("\""); 
// find first occurrence of a double quotation mark and assign position value to pos1
            int pos2 = line.rfind("\""); 
// find last occurrence of a double quotation mark and assign position value to pos2

            string message = line.substr(pos1, (pos2 - pos1)); 
// sets message to string between quotation marks

            string restOfLine = line.substr(pos2 + 2); 
// restOfLine = everything after the message -- used to parse

        }

        inFile.close();
    }

    // If file open failure, output error message, exit with return 0;

    else
    {

        cout << "Error opening file";

    }

    return 0;

}
  • Do you already know [stringstream](http://stackoverflow.com/questions/20594520/what-exactly-does-stringstream-do)s? – Bob__ Feb 27 '17 at 09:44

2 Answers2

1

I'm wondering if there is a function similar to inFile >> var1 >> var2 >> etc; that I can use for a string?

Yes, and not just similar, identical in fact. string streams work the same as file streams.

std::stringstream ss(restOfLine);
ss >> numMedium >> numLarge >> numXL >> shirtColor >> inkColor >> firstName >> lastName >> customerEmail >> firstLine;
acraig5075
  • 10,588
  • 3
  • 31
  • 50
0
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
unsigned int split(const std::string &txt, std::vector<std::string> &strs, char ch);
    int main(int argc, const char * argv[]) {

    string text = "2016/12/6 s \"The incestuous relationship between government and big business thrives in the dark. ~Jack Anderson [4]\" 0 3 39 blue white PATRICK BARDWELL pat.bardwell@bwpmlp.com ";
    std::vector<std::string> v;

    split( text, v, ' ' );
    return 0;
}

unsigned int split(const std::string &txt, std::vector<std::string> &strs, char ch)
{
    unsigned int pos = static_cast<unsigned int>(txt.find( ch ));
    unsigned int initialPos = 0;
    strs.clear();

    // Decompose statement
    while( pos >! txt.size()) {
        strs.push_back( txt.substr( initialPos, pos - initialPos + 1 ) );
        initialPos = pos + 1;

        pos = static_cast<unsigned int>(txt.find( ch, initialPos));
        if(pos > txt.size()) break;
    }

    // Add the last one
//    strs.push_back( txt.substr( initialPos, std::min( pos, static_cast<unsigned int>(txt.size() )) - initialPos + 1 ) );

    return static_cast<unsigned int>(strs.size());
}

So above program will breakdown your strings into parts then use below mentioned functions for data type conversion. To convert string to int you can use std::stoi( str ) this is available in C++11. There are version for all type of numbers: long stol(string), float stof(string), double stod(string),... see http://en.cppreference.com/w/cpp/string/basic_string/stol for more info.