Handling string inputs in C/Linux

ambuli
ambuli used Ask the Experts™
on
Hi there,

I have a function which accpets user inputs as strings. I am expecting
to receive variable number of arguments.

The first word would be a command and the next few the required data
for the command(if required)

Is there a better way to do this rather than parsing the input
and separating each words etc...  ( this function is not the main entry point of the program)...


void handleInputCommand(char *input)
{
     if(strcmp("doJob1", input0)== 0)
     {
        doJob1();
	...
     }
     else if(strcmp("doJob2", input0) == 0)
     {
         doJob2(param1);
     }
}

Open in new window

Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Karrtik IyerSoftware Architect

Commented:
Is it C or C++? In topics you have added C++ but in question you  have specified C.
Karrtik IyerSoftware Architect

Commented:
Use like input parameters to main function (int argc, char** argv), assuming this is in C.
Something like below.
void handleInputCommand(int count, const char * input[]){
     if(strcmp("doJob1", input[0])== 0)
     {
        doJob1();
	...
     }
     else if(strcmp("doJob2", input[0]) == 0)
     {
         doJob2(param1);
     }
}

Open in new window

Most Valuable Expert 2014
Top Expert 2015
Commented:
#include <iostream>
#include <map>
#include <functional>
using std::cout;
using std::endl;
using std::string;
void doJob1(){
  cout << "Job1" << endl;
}
void doJob2(const string &param){
  cout << "Job2(" << param << ")" << endl;
}
void handleInputCommand(char *input)
{
  const string param1="param1";
  std::map<string,std::function<void()>>job={
        {"doJob1",doJob1},
        {"doJob2",[param1](){doJob2(param1);}}
  };
  (job.count(input)?job[input]:[input](){cout << "unknown input " << input << endl;})();
}
int main(){
  handleInputCommand("doJob1");
  handleInputCommand("doJob2");
  handleInputCommand("doJob3");
}
Ensure you’re charging the right price for your IT

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden using our free interactive tool and use it to determine the right price for your IT services. Start calculating Now!

evilrixSenior Software Engineer (Avast)
Commented:
If this is more than a couple of simple commands you are better off defining a formal grammar, using something like EBNF, and then creating a parser. You can use Boost Spirit to code a static parser in C++. If you're not expecting to support more than a couple of commands you are probably better of using the built in regex support in C++.

I would avoid manually hard coding a parser as they are hard to test, hard to maintain and usually end up being very brittle, rigid and a monster to support.
murugesandinsShell_script Automation /bin/bash /bin/bash.exe /bin/ksh /bin/mksh.exe AIX C C++ CYGWIN_NT HP-UX Linux MINGW32 MINGW64 SunOS Windows_NT

Commented:
In given programs:
Replace lines like:
if(strcmp("doJob1", input[0])== 0)
With:
if ( 0 == strcmp("doJob1", input[0]))

Replace:
handleInputCommand("doJob3");
 }
With:
      handleInputCommand("doJob3");
      return 0; // Required for echo $? at Linux/SunOS/AIX/HP-UX/Cygwin_Windows
 }
Karrtik IyerSoftware Architect

Commented:
Hi Ambuli,
Would like to know why the solution provided by me would not work given that in the question you have mentioned that you want to know how to handle strings in C/Linux?
Immediately after your question was posted, I requested you to clarify if it was on C or C++ that you wanted solution on. Since I did not receive any response, I provided a solution in C with an assumption.
Also both the solution that you have accepted are C++ solutions (I do not have any issues with it), however I believe my solution is a feasible and viable option in C. Hence I would like to have this clarified.
Thanks,
Karrtik
evilrixSenior Software Engineer (Avast)

Commented:
Um, read my comment again.
What I say is language agnostic, but goes on to point out that there are ready made solutions for C++. That doesn't make it any less valid for C. Also, the asker does not have to explain their disposition to you. As long gone as valid answers are chosen (they are) how the asker chooses to close a question is really up to them.

The actual question asked was: Is there a better way to do this rather than parsing the input

If you want to be pedantic about it I'd argue the only person who answered that question directly was me! I suggest if you truly object to the closure that you click "request attention" and ask the mods to review; however, unless you can give a good reason why, they are unlikely to overrule the asker's decision.
Karrtik IyerSoftware Architect

Commented:
evilrix, I raised an attention request and based on their input I posted this comment.
evilrixSenior Software Engineer (Avast)

Commented:
I'm also unclear on how you believe your comment helps the asker! Command line arguments are not really considered "user input"  and the asker makes the point, "and separating each words etc...  ( this function is not the main entry point of the program".
Karrtik IyerSoftware Architect

Commented:
evilrix, While your answer was partially language agnostic (in terms of formal grammar and EBNF). But to put in author's comment, he asked specifically for a solution in C. As I said, I do not have any issues with accepted solutions or points, however when I asked author for clarification immediately whether he wanted it for C or C++, I never received any response. Please refer to my first comment in this chain.
Karrtik IyerSoftware Architect

Commented:
evilrix, I did not suggest command line arguments, I suggested function to have parameters similar to main function so that size of the array is known along with array of strings as input. This was because in C I could not have proposed containers such as map or use of boost libraries.
evilrixSenior Software Engineer (Avast)

Commented:
Right, but the asker wants to know how to deconstruct a string, so how does that help? Unless the asker codes up a special input routine or places restrictions on how the commands are entered there is no way to avoid the need to decompose a string.

My comment is completely language agnostic other than pointing out if the asker is using C++ there are ready made solutions.  You can still get EBNF parser generators (Bison or YACC for exaple) and regex  engines (PCRE for example) for C ; however,  since one of these are either part of C nor a DSL (Domain Specific Language) written see for integrated use in C,  there was little point in waffling on about them. The options in C are varied and really up to the asker. In C++ (should the asker decide to go that way,  given most C compilers are C++ compilers, too and so will quite happily link in C++) the asker has precoded solutions that might be used.
Karrtik IyerSoftware Architect

Commented:
And for that reason only I had asked the author whether he wants solution in C or  C++, like as per your last comment, as it did made hardly any sense for you waffling about your suggested options in C since they are neither part of C nor DSL, similarly it made little sense for me to provide solutions in C++ since his question explicitly stated C and without receiving the clarification in which programming language he wanted options.
evilrixSenior Software Engineer (Avast)

Commented:
Yeah, except it doesn't actually answer the question asked.

Anyway, you've clicked RA so I'm sure the mods will sort it out. :)

Have a good day.
evilrixSenior Software Engineer (Avast)

Commented:
KarrtikIyer, btw I've just invited you to join the regular contributing expert C/C++ group. 😄
Karrtik IyerSoftware Architect

Commented:
Thanks a lot evilrix :)
Karrtik IyerSoftware Architect

Commented:
Hi Evilrix, I agree that we can leave this to the moderators, that's what I did in first place but since you had some questions and comments, I thought it is better to share my thoughts on the same.
Just to answer to your last post that actual question does not get solved by my solution. (Your last post)
I disagree with it. If you look at the original question, the author does not want to parse a single string (char array) to get command name and parameters following it as words. Which is parsing a single string to get the first word as command and rest as input if required.
And if you read my solution, I suggested to author, not to pass the input as a single string, instead pass it as array of strings (char* input[] and count of strings in this array), so that no parsing is needed.
It can well be argued if the string is coming from external source (as bytes from socket) then still it has to be parsed to form the array of strings that I suggested. But there are equal chances that this function is internally called, and the input string is also constructed internally (author has mentioned that this is not the main entry part of the program) and not coming from any external source, in which case, there is no parsing involved and directly the author can create an array of strings instead of a single string which he planned to parse in his original question.
The main intent was to avoid parsing a single string to form different words.
Have a nice weekend.

Thanks and regards,
Karrtik
evilrixSenior Software Engineer (Avast)

Commented:
So, you accept there is a 50% chance your solution is of no use to the asker? So, that means there was only a 50% chance they'd accept it? I think you've answered your own question.
Karrtik IyerSoftware Architect

Commented:
The same is true for your solution (50% right) if author wanted solution only for C, as stated in the question. And if he didn't want any programming language agnostic concepts based on the title of his question. :)
I guess I deserve an explanation when I had explicitly asked for which programming language he targetted.
So I'm not sure why you think I should not have raised this attention request and not raised this objection?
So you agree that your previous post was incorrect that my solution doesn't solve the problem posed by author at all.
For sake of argument we can keep arguing as much as we want, my only point in my objection was since the question stated C and author never clarified my question on in which programming language he wants the solution, my solution is viable for C.

Thanks,
Karrtik
evilrixSenior Software Engineer (Avast)

Commented:
Yeah, but there are two important differences:

1. My advise is language agnostic*.
2. The asker accepted my answer.

So, on balance isn't it just likely that the author preferred my and ozo's answer? I mean, the answers selected are perfectly valid.

Your solution may be valid given very specific criteria. The fact the asker never accepted it suggests it doesn't meet the criteria. It's up to the asker if they wish to clarify ;however, they are based near no obligation to do so.

Also, I have no issue with you creating a request for Mod attention, I'm just explaining why I'd not have bothered. As a Topic Advisors that's sort of part of my remit.

Anyway, let us see what the mods say.

* My recommendation was to create a formal grammar or use regex, nether of which is specific to any language and just as valid for C as C++. The note that both are easy to accommodate in C++ was additional information, so it is disingenuous to keep implying my answer is C++ specific. It's not! Even so, to change a C program to build/link C++ is trivial.
Karrtik IyerSoftware Architect

Commented:
Please read my request again, I never said that accepted answers are invalid. I only said that my solution would also work in C in my objection.
And I never said that anyone is obliged to answer but I have rights to ask and I think at least I provided enough explanation so far to suggest that it's not totally rubbish to seek it in this case. And I don't raise objections unnecessarily, as a topic owner you can check that. However thanks for your advice.
In addition if you look at the history of questions asked by the author they are primarily targetted for C. While your solution is not c++ specific, on my part it is fair to think based on previous questions from the author, that he needed a solution for C. And I never objected to your solution.
I also think that a string split based on delimiters (calling a function like strtok) would have given author the necessary array of strings necessary to pass to my suggested solution. So even if the string (char array) came from external source, it would have been pretty straight forward.
evilrixSenior Software Engineer (Avast)

Commented:
Your solution may work in C, but that doesn't mean the asker either has to choose or explain why they didn't. All the asker is required to do is select that which they find helpful. That's all I am saying; no more and no less.

Anyway, I think we've discussed this to completion. Thanks for the discussion. Feel free to ping me anytime if you need any TA help and feel free to participate in the group I invited you to. Have a great weekend.
Karrtik IyerSoftware Architect

Commented:
Sure, thanks evilrix, it was a nice discussion, you too have a nice weekend. Thanks for inviting me to the group.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial