Parsing Commands
Apr 20, 2013 at 8:38pm UTC
Is there a better way to parse words in a string to pass as "commands for the console"? I'm making a customized CLI, and have a whole bunch of if statements like so:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
if (line[x] == 'a' ) {
}
if (line[x] == 'b' ) {
} // BELOW IS WHAT I WANT TO ELIMINATE: PARSING CHAR BY CHAR
if (line[x] == 'c' ) {
if (line[x+1] == 'o' ) {
if (line[x+2] == 'l' ) {
if (line[x+3] == 'o' ) {
if (line[x+4] == 'r' ) {
SetColor(10);
}
}
}
}
}
/*
if (line[x] == 'd') {
}
if (line[x] == 'e') {
}
if (line[x] == 'f') {
}
if (line[x] == 'g') {
}
if (line[x] == 'h') {
}
if (line[x] == 'i') {
}
if (line[x] == 'j') {
}
if (line[x] == 'k') {
}
if (line[x] == 'l') {
}
if (line[x] == 'm') {
}
if (line[x] == 'n') {
}
if (line[x] == 'o') {
}
if (line[x] == 'p') {
}
if (line[x] == 'q') {
}
if (line[x] == 'r') {
}
if (line[x] == 's') {
}
if (line[x] == 't') {
}
if (line[x] == 'u') {
}
if (line[x] == 'v') {
}
if (line[x] == 'w') {
}
if (line[x] == 'x') {
}
if (line[x] == 'y') {
}
if (line[x] == 'z') {
} */
Is there any way to parse a command (below) to make the console set the color to lime green? (<-- I know how to do that, but how do I parse the command with switches/parameters?)
color -lg
Last edited on Apr 20, 2013 at 8:38pm UTC
Apr 20, 2013 at 8:44pm UTC
man getopt
Apr 20, 2013 at 8:53pm UTC
well for one you could input a string by using getline(cin, stringname); and that would get rid of the having to if 'c' if 'o' ect..for color but the color code eg 'l'g' might be a bit more difficult for the switch since switches are in this formart switch(char), switch(int) and not switch(string) but you could convert the letters to numbers then change color based on that.
and then you could do soemthing like
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
#include <iostream>
#include <stdlib.h>
using namespace std;
int main()
{
string input, error, colorCodeStr;
unsigned int colorCode;
do {
cout << "Which color would you like?: " << flush;
getline(cin, input);
for (unsigned int i = 0; i<input.size(); i++) if (isdigit(input[i])) error = "true" ; else error = "false;
} while(error == " true ");
switch(input[0]){
case 'l': colorcodeStr[0] = '0'; break;
}
switch(input[1]){
case 'g': colorCodeStr[1] = '0'; break;
}
colorCode = atoi(colorCodeStr.c_str());
switch(colorCode){
case 00: setColor(10); break;
}
}
didn't tesat the code its just an thought that you could try.
Last edited on Apr 20, 2013 at 8:54pm UTC
Apr 20, 2013 at 9:12pm UTC
@ne555 - I've looked at the examples on GNU.org, and apparently I can't modify it to fit my needs:
1 2 3 4 5 6 7 8 9
while ((c = getopt (args, argv2, "-:" )) != -1) {
switch (c) {
case '-' :
col = optarg;
cout << col;
getchar();
break ;
}
}
I want it to output "col", but it doesn't. Ideas? Full code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
#include <iostream>
#include <algorithm>
#include <unistd.h>
#include <string>
#include <windows.h>
#include <fstream>
#include <vector>
using namespace std;
void SetColor(unsigned short color) {
HANDLE hcon = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hcon, color);
}
BOOL WINAPI SetConsoleIcon(HICON hIcon) {
typedef BOOL (WINAPI *PSetConsoleIcon)(HICON);
static PSetConsoleIcon pSetConsoleIcon = NULL;
if (pSetConsoleIcon == NULL)
pSetConsoleIcon = (PSetConsoleIcon)GetProcAddress(GetModuleHandle(("kernel32" )), "SetConsoleIcon" );
if (pSetConsoleIcon == NULL)
return FALSE;
return pSetConsoleIcon(hIcon);
}
int main(int argc, char * argv[])
{
SetConsoleTitle("Cmd2" );
HICON hIcon = LoadIcon(GetModuleHandle(0),"MAINICON" );
SetConsoleIcon(hIcon);
if (argc<2) {
cerr << "Cmd2\n\n" ;
getchar();
} else {
int args;
char * argv2[5];
char * col = NULL;
string line;
int c;
string cmd;
ifstream file;
file.open(argv[1]); // Args start a 0, then go up by 1. argv[0] is the Program path.
if (!file.is_open()) {
file.close();
cout << "Error opening file." ;
getchar();
} else {
while (!file.eof()) { // While the file isn't ended
getline(file, line); // get the command's whole line
if (!line.empty()) { // If the line isn't empty...
for (unsigned int i = 0; i < line.length(); i++) { // Tranform string to lowercase
tolower(line[i]);
}
for (unsigned int x = 0; x < line.length(); x++) {
if (line[x] != ' ' ) {
cmd += line[x];
} else {
while ((c = getopt (args, argv2, "-:" )) != -1) {
switch (c) {
case '-' :
col = optarg;
cout << col;
getchar();
break ;
}
}
}
}
}
}
}
file.close();
}
cout << "Command Completed Successfully." ;
getchar();
}
@giblit - Seems like it would work, but I think I'll go with ne555's way.
Apr 20, 2013 at 9:26pm UTC
You never initialize args or argv2.
¿how are you using it?
Last edited on Apr 20, 2013 at 9:27pm UTC
Apr 20, 2013 at 9:30pm UTC
Yes I do. Check the code again:
1 2 3 4 5 6 7
} else {
int args;
char * argv2[5];
char * col = NULL;
string line;
int c;
string cmd;
Apr 20, 2013 at 9:33pm UTC
int args;
is not initialization ¿what value does `args' hold?
By the way,
will take `c' `o' and `l' as options (as long as no one expects a value)
Apr 20, 2013 at 9:36pm UTC
So all I do is change it to int args = 0;
and char * argv2[5] = {NULL, NULL, NULL, NULL, NULL};
?
Apr 20, 2013 at 9:40pm UTC
¿and what would that do?
You'll parse nothing.
Apr 20, 2013 at 10:01pm UTC
So how do I parse like I want to do like stated in the OP?
Apr 20, 2013 at 11:48pm UTC
./program.bin -b red -f green
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
int main(int argc, char **argv){
int opt;
std::string optstring;
while ( (opt=getopt(argc, argv, "b:f:" )) != -1 ){
switch (opt){
case 'b' :
colour = optstring; //red
break ;
case 'f' :
colour = optstring; //green
break ;
default :
std::cerr << "unknow option " << opt;
}
}
}
Also take a look at `getopt_long'
Last edited on Apr 20, 2013 at 11:48pm UTC
Apr 21, 2013 at 1:40am UTC
That seems to be for the main arguments. The file that I'm trying to parse has color -c 10
in it. How do I parse such a thing?
Apr 21, 2013 at 2:27pm UTC
I've found a way to do this right, but can't seem to correctly parse the commands. Here's the full code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
#include <iostream>
#include <string>
#include <windows.h>
#include <fstream>
#include <vector>
#include <sstream>
using namespace std;
void SetColor(unsigned short color) {
HANDLE hcon = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hcon, color);
}
BOOL WINAPI SetConsoleIcon(HICON hIcon) {
typedef BOOL (WINAPI *PSetConsoleIcon)(HICON);
static PSetConsoleIcon pSetConsoleIcon = NULL;
if (pSetConsoleIcon == NULL)
pSetConsoleIcon = (PSetConsoleIcon)GetProcAddress(GetModuleHandle(("kernel32" )), "SetConsoleIcon" );
if (pSetConsoleIcon == NULL)
return FALSE;
return pSetConsoleIcon(hIcon);
}
int main(int argc, char * argv[])
{
SetConsoleTitle("Cmd2" );
HICON hIcon = LoadIcon(GetModuleHandle(0),"MAINICON" );
SetConsoleIcon(hIcon);
if (argc<2) {
cerr << "Cmd2" ;
} else {
string line;
string cmd;
string params;
string token;
unsigned int i;
unsigned int x = 0;
ifstream file;
file.open(argv[1]); // Args start a 0, then go up by 1. argv[0] is the Program path.
if (!file.is_open()) {
file.close();
cout << "Error opening file." ;
} else {
int words = 0;
string word;
while (file >> word) {
words++;
}
string tokens[words];
while (!file.eof()) { // While the file isn't ended
getline(file, line); // get the command's whole line
if (!line.empty()) { // If the line isn't empty...
for (i = 0; i < line.length(); i++) { // Tranform string to lowercase
tolower(line.at(i));
}
stringstream ss(line);
while (getline(ss, token, ' ' )) {
tokens[x] = token;
x++;
}
}
}
unsigned int y = 0;
while (y <= x) {
if (tokens[y] == "color" ) {
if (tokens[y+1] == "-lime" ) {
SetColor(10);
}
}
y++;
}
cout << "Command Completed Successfully.\n" ;
}
file.close();
}
getchar();
}
Topic archived. No new replies allowed.