Reputation: 11
I want to hold a string with spaces therefore I used getline()
but after it I want to get another string(no spaces) if there is a -e
for example and the string after it in s2
, but since in my code I lose the dash when using getline()
I can't seem to achieve what I'm trying to do. any suggestions would be really helpful.
//example input: -f name -b blah blah -e email
//looking for output:
//name
//blah blah
//email
string s,s1,s2;
char check_character;
while (cin.peek() != '\n')
{
if (cin.get() == '-')
{
check_character = cin.get();
switch(check_character)
{
case 'f':
cin >> s;
break;
case 'b':
if(cin.peek() != '\n')
getline(cin, s1, '-');
else if(cin.peek() =='\n')
getline(cin, s1);
break;
case 'e':
cin>> s2;
break;
}
}
}
cout << s << endl << s1 << endl << s2 << endl;
return 0;
}
Upvotes: 1
Views: 1980
Reputation:
I think you should put cin.ignore before typing getline as in your code:
`string s,s1,s2;
char check_character;
while (cin.peek() != '\n')
{
if (cin.get() == '-')
{
check_character = cin.get();
switch(check_character)
{
case 'f':
cin >> s;
break;
case 'b':
if(cin.peek() != '\n')
cin.ignore
getline(cin, s1, '-');
else if(cin.peek() =='\n')
cin.ignore
getline(cin, s1);
break;
case 'e':
cin>> s2;
break;
}
}
}
cout << s << endl << s1 << endl << s2 << endl;
return 0; `
Upvotes: 0
Reputation: 6240
The way you parse the arguments could certainly be improved, but this answer is not about it. I think what you are looking for is to simply put the -
char back into the stream after std::getline
removed it. In this case you could just use .putback()
method
if (std::cin.peek() != '\n')
{
std::getline(std::cin, s1, '-');
std::cin.putback('-');
}
Upvotes: 0
Reputation: 5321
If you go the approach of reading in the entire line, and you do not want to use Boost program options, or getopts, you could parse the line yourself (as has been suggested). Here would be one way of doing it, as an alternative of parsing on the fly in your code:
#include <iostream>
#include <string>
#include <tuple>
#include <vector>
using std::cout;
using std::endl;
using std::get;
using std::literals::string_literals::operator""s;
using std::make_tuple;
using std::string;
using std::tuple;
using std::vector;
static auto chunkLine(string const& line)
{
auto result = vector<string>{};
auto i = string::size_type{};
while (i != string::npos && i < line.size())
{
auto pos = line.find(" -", i);
auto count = pos == string::npos ? pos : (pos - i);
result.push_back(line.substr(i, count));
i = pos + (pos != string::npos ? 1 : 0);
}
return result;
}
static auto parseChunks(vector<string> const& chunks)
{
auto result = vector<tuple<string, string>>{};
for (auto const& chunk : chunks)
{
auto pos = chunk.find(" ");
if (pos != string::npos && chunk[0] == '-')
{
auto kv = make_tuple(chunk.substr(1, pos-1), chunk.substr(pos+1));
result.push_back(kv);
}
}
return result;
}
int main()
{
auto line = "-f name -b blah blah -e email"s;
auto keyValueTuples = parseChunks(chunkLine(line));
for (auto const& kv : keyValueTuples)
{
cout << get<1>(kv) << endl;
}
}
Upvotes: 0
Reputation: 38969
I'm going to make a couple assumptions here:
A regex_search
will handle this nicely with the regex
:
(?:\s*-f\s+(\w+)|\s*-b\s+([^-]+)|\s*-e\s+(\w+))*
You'll need to start by reading from cin
into a variable, for example string input
. This could be done like:
getline(cin, input)
Once you have your input you can simply do:
if(smatch m; regex_search(input, m, regex{ "(?:\\s*-f\\s+(\\w+)|\\s*-b\\s+([^-]+)|\\s*-e\\s+(\\w+))*" })) {
if(m[1].length() > 0U) {
cout << "-f " << m[1] << endl;
}
if(m[2].length() > 0U) {
cout << "-b " << m[2] << endl;
}
if(m[3].length() > 0U) {
cout << "-e " << m[3] << endl;
}
}
Upvotes: 0
Reputation: 46
getline()
extracts characters from is and stores them into str until the delimitation character delim is found or the newline character, '\n'
.
If the delimiter is found, it is extracted and discarded (i.e. it is not stored and the next input operation will begin after it).
Upvotes: 1
Reputation: 959
A better option would be to do a single call to getline()
then parse the "command" string. There are many options of achieving this, from a simple split()
on "-" or find('-')
Upvotes: 1