-
Stdin Line Parsing C++
Hello all, I'm working on a simple drawing program in C++ that out puts postscript commands. Since I'm still pretty new to C++, I'm not sure if there is a better and more reliable way to dissect the input that I'm getting from the user.
The input looks like this:
Any amount of whitespace (including 0) is allowed between a parenthesis and the start or end of a command, and between commands. At least one character of whitespace is required to separate arguments within a command.
For example, the following would draw a thick green square, rotated 45 degrees.
(linewidth 5)
(color 0 0 1)
(linear 0.7071 0.7071 -0.7071 0.7071)(rect 100 100 100 100)
My current parse looks like this:
Code:
while(getline(cin, s1))
{
cstr = new char [s1.size()+1];
strcpy (cstr, s1.c_str());
p = strtok (cstr," ()");
s2 = p;
do
{
s2 = p;
if(s2.compare("color") == 0){
......
}
if(s2.compare("linewidth") == 0){
......
}
if(s2.compare("line") == 0){
......
}
if((s2.compare("rect") == 0) || (s2.compare("filledrect") == 0)){
......
}
if((s2.compare("tri") == 0) || (s2.compare("filledtri") == 0)){
......
}
if((s2.compare("square") == 0) || (s2.compare("filledsquare") == 0)){
......
}
}while(p = strtok (NULL," ()"));
This works well for the one line inputs like the color or linewidth but as seen in the above example input there can be a bunch of linears on the same line followed by a shape. I know there is a better way to parse the lines i get but i can't seem to figure it out. i was messing around with while and do while loops and came up with this. Any comments/feedback would be greatly appreciated!
-
not sure if this will work but worth a try
first replace all '(' with spaces , then replace all ')' with new lines
then insert into a stream and use getline on it...for each line insert it into a stream and parse it.
Code:
#include <algorithm>
#include <string>
#include <sstream>
int main()
{
string command;
while( getline(cin, command) )
{
replace(command.begin(), command.end(), '(', ' ');
replace(command.begin(), command.end(), ')', '\n');
istringstream iss(command);
string parted_command;
while( getline( iss, parted_command) )
{
istringstream iss2(parted_command);
string argument;
iss2 >> argument;
int current_number;
while( iss2 >> current_number)
{
//work with the number depending on the what argument is.
}
}
}
}
-
The line issue seems to be a red herring, since it seems that any amount of any commands can appear on the same physical line (and that it's just coincidence that some of your example commands are on a line by themselves). You can use the extra parameter to getline to say "read until this particular character" to get everything up to the closing ). (This assumes that parentheses can't appear inside a command.)