Search code examples
c++stringvectortokenizec++98

After tokenizing string with hypen '-', hypen will get eliminated!! how to fix this in c++98


below shell script saved file name as add.sh

#!/bin/sh

MY_EXEC="add";

add -Units 32 -raid 111 -log add.log 

My code will read this file add.sh and store contents in vector. the vector[2] string content i,e "add -Units 32 -raid 111 -log add.log" will be tokenized using '-'. after this o/p for this code will be like this below.

add
Units 32
raid 111
logFile add.log

where the expected result is below, where after tokenize the '-' shouldn't get eliminated, how to fix this?

add
-Units 32
-raid  111
-logFile add.log

Program code:

#include <iostream>
#include <string>
#include <vector>
#include <cstdlib>
#include <fstream>
#include <sstream>
#include <algorithm>
#include <cctype>
#include <utility>
  
using namespace std;
/*
 * It will iterate through all the lines in file and
 * put them in given vector
 */
bool getFileContent(string fileName, vector<string> & vecOfStrs)
{
    // Open the File
    ifstream in(fileName.c_str());
    // Check if object is valid
    if(!in)
    {
        cerr << "Cannot open the File : "<<fileName<<endl;
        return false;
    }
    string str;
    // Read the next line from File until it reaches the end.
    while (getline(in, str))
    {
        // Line contains string of length > 0 then save it in vector
        if(str.size() > 0)
            vecOfStrs.push_back(str);
    }
    //Close The File
    in.close();
    return true;
}
int main()
{
    vector<string> vecOfStr;
    vector <string> tokens;
    // Get the contents of file in a vector
    bool result = getFileContent("add.sh", vecOfStr);
    string str = vecOfStr[2].c_str();
    string intermediate;

    // stringstream class check1
    stringstream check1(str);

    // Tokenizing w.r.t. space '-'
    while(getline(check1, intermediate, '-'))
    {
        tokens.push_back(intermediate);
    }

    // Printing the token vector
    for(int i = 0; i < tokens.size(); i++)
        cout << tokens[i] << '\n';

    return 0;
}

Solution

  • If the only requirement is to get the expected output, you could use a space (' ') as the delimiter and modify the printing.

    int main()
    {
        vector<string> vecOfStr;
        vector <string> tokens;
        // Get the contents of file in a vector
        bool result = getFileContent("add.sh", vecOfStr);
        string str = vecOfStr[2].c_str();
        string intermediate;
    
        // stringstream class check1
        stringstream check1(str);
    
        // Tokenizing w.r.t. space
        while(getline(check1, intermediate, ' '))
        {
            tokens.push_back(intermediate);
        }
    
        // Printing the token vector
        for(int i = 0; i < tokens.size(); i++)
        {
            if(tokens[i][0] == '-')
            {
                cout << endl;
            }
            else
            {
                if(i != 0) cout << ' ';
            }
            cout << tokens[i];
        }
        cout << endl;
    
        return 0;
    }
    

    Or if you want to have the option and the value combined as one value in the tokens vector you can modify the values in the vector accordingly.

    static constexpr char delimiter = ' ';
    
    int main()
    {
        vector<string> vecOfStr;
        vector <string> tokens;
        // Get the contents of file in a vector
        bool result = getFileContent("add.sh", vecOfStr);
        string str = vecOfStr[2].c_str();
        string intermediate;
    
        // stringstream class check1
        stringstream check1(str);
    
        // Tokenizing w.r.t. space
        while(getline(check1, intermediate, delimiter))
        {
            // non-option value found and already a value stored in the vector?
            if((intermediate[0] != '-') && (!tokens.empty()))
            {
                // combine previous and current token
                intermediate = tokens.back() + delimiter + intermediate;
                // and remove previous one from vector
                tokens.pop_back();
            }
            tokens.push_back(intermediate);
        }
    
        // Printing the token vector
        for(int i = 0; i < tokens.size(); i++)
            cout << tokens[i] << endl;
    
        return 0;
    }