Building command line applications - c++

How can I move away from (in c++) the annoying menus like:
(a) Do something
(b) Do something else
(c) Do that 3rd thing
(x) exit
Basically I want to be able to run the program then do something like "calc 32 / 5" or "open data.csv", where obviously I would have written the code for "calc" and "open". Just a shove in the right direction would be great, I am sure I can figure it all out, I just need something to google-fu.

I think you want to do something like this:
string cmd;
cout << "Enter your command:" << endl;
cin >> cmd;
if(cmd == "open") {
// read file name and open file
} else if (cmd == "calc") {
// read and evaluate expression
} ...
Though depending on how complex you want your command language to be, a more elaborate design (maybe even using a parser generator) might be appropriate.

You should pick up The C++ Programming Language, which is the book on C++ (there are others, but this one is great). It has an example program, spread over a few chapters, on tokenizing, parsing arguments, and making a calculator.

What you want is a command line parser. I can't remember the name, but there is actually a design pattern to this. However, this site gives you some sample code you can use to write one. Hope that's not giving you too much of the answer :)

Instead of looking for input like a, b, etc, just ask for generic input. Split the input at spaces, do a "switch" on the first one to match it up to your function calls, treat the rest as arguments.

Is your menu based on a call to getchar()? If you want to allow entering an entire line before processing it, you can use fgets() or, in C++ land, std::getline.

Some folks will package their C++ class definitions as Python classes by adding a Python interface to the C++.
Then they write the top-level interpreter in Python using the built-in cmd library.

Take a look to:
ANTLR which is a very good and easy parser which also generates code on C++.
You can take a look to Natural CLI (java) to get inspired. (Disclaimer: i'm the developer of that project).

Related

How can i write text in c++ console without breaking the lines

how can i input text in c++ console without breaking the input in one line at a time?
If i use cin i can input one string each time plus i cannot edit the input (except if i edit the string but this wont help)
Is there any way to input strings (with multiple lines) but not to break the string in one line at a time?
I am running ubuntu 12.04
Who is writing? Is it you, or some program??
Your terminology is unusual: generally programmers take the point of view of the computer!
What you write by typing on your keyboard is an input to some program (which reads it).
If you want an editable input (to the program, so "written" or typed by the human user), consider using GNU readline (on Linux), or perhaps ncurses
If you want to format the program's output (which the user would read with his eyes), you'll generally need to code that formatting explicitly. Perhaps ANSI escape codes might be useful (but using them might make readline or ncurses unhappy).
See also this answer and the references I gave there.

Linux Printing - How To

I find it hard to explain but I will try my best. Some times in Linux- in the Terminal- things get printed but you can still write over them. eg when using wget you get a progress bar like this:
[===================> ]
Now if you type something while it is doing this it will 'overwrite' it. My question is how to recreate this in c++.
Will you use something like
cout <<
or something else?
I hope you understand what I am getting at...
btw I am using the most recent version of Arch with xfce4
Printing a carriage return character \r is typically interpreted in Linux as returning you to the beginning of the line. Try this, for example:
std::cout << "Hello\rJ";
The output will be:
Jello
This does depend on your terminal, however, so you should look up the meaning of particular control characters for your terminal.
For a more cross-platform solution and the ability to do more complex text-based user interfaces, take a look at ncurses.
You can print the special character \b to go back one space. Then you can print a space to blank it out, or another character to overwrite what was there. You can also use \r to return to the beginning of the current output line and write again from there.
Controlling the terminal involved sending various escape sequences to it, in order to move the cursor around and such.
http://www.ibiblio.org/pub/historic-linux/ftp-archives/tsx-11.mit.edu/Oct-07-1996/info/vt102.codes
You could also use ncurses to do this.

Creating a simple parser in (V)C++ (2010) similar to PEG

For an school project, I need to parse a text/source file containing a simplified "fake" programming language to build an AST. I've looked at boost::spirit, however since this is a group project and most seems reluctant to learn extra libraries, plus the lecturer/TA recommended leaning to create a simple one on C++. I thought of going that route. Is there some examples out there or ideas on how to start? I have a few attempts but not really successful yet ...
parsing line by line
Test each line with a bunch of regex (1 for procedure/function declaration), one for assignment, one for while etc...
But I will need to assume there are no multiple statements in one line: eg. a=b;x=1;
When I reach a container statement, procedures, whiles etc, I will increase the indent. So all nested statements will go under this
When I reach a } I will decrement indent
Any better ideas or suggestions? Example code I need to parse (very simplified here ...)
procedure Hello {
a = 1;
while a {
b = a + 1 + z;
}
}
Another idea was to read whole file into a string, and go top down. Match all procedures, then capture everything in { ... } then start matching statements (end with ;) or containers while { ... }. This is similar to how PEG does things? But I will need to read entire file
Multipass makes things easier. On a first pass, split things into tokens, like "=", or "abababa", or a quote-delimited string, or a block of whitespace. Don't be destructive (keep the original data), but break things down to simple chunks, and maybe have a little struct or enum that describes what the token is (ie, whitespace, a string literal, an identifier type thing, etc).
So your sample code gets turned into:
identifier(procedure) whitespace( ) identifier(Hello) whitespace( ) operation({) whitespace(\n\t) identifier(a) whitespace( ) operation(=) whitespace( ) number(1) operation(;) whitespace(\n\t) etc.
In those tokens, you might also want to store line number and offset on the line (this will help with error message generation later).
A quick test would be to turn this back into the original text. Another quick test might be to dump out pretty-printed version in html or something (where you color whitespace to have a pink background, identifiers as light blue, operations as light green, numbers as light orange), and see if your tokenizer is making sense.
Now, your language may be whitespace insensitive. So discard the whitespace if that is the case! (C++ isn't, because you need newlines to learn when // comments end)
(Note: a professional language parser will be as close to one-pass as possible, because it is faster. But you are a student, and your goal should be to get it to work.)
So now you have a stream of such tokens. There are a bunch of approaches at this point. You could pull out some serious parsing chops and build a CFG to parse them. (Do you know what a CFG is? LR(1)? LL(1)?)
An easier method might be to do it a bit more ad-hoc. Look for operator({) and find the matching operator(}) by counting up and down. Look for language keywords (like procedure), which then expects a name (the next token), then a block (a {). An ad-hoc parser for a really simple language may work fine.
I've done exactly this for a ridiculously simple language, where the parser consisted of a really simple PDA. It might work for you guys. Or it might not.
Since you mentioned PEG i'll like to throw in my open source project : https://github.com/leblancmeneses/NPEG/tree/master/Languages/npeg_c++
Here is a visual tool that can export C++ version: http://www.robusthaven.com/blog/parsing-expression-grammar/npeg-language-workbench
Documentation for rule grammar: http://www.robusthaven.com/blog/parsing-expression-grammar/npeg-dsl-documentation
If i was writing my own language I would probably look at the terminals/non-terminals found in System.Linq.Expressions as these would be a great start for your grammar rules.
http://msdn.microsoft.com/en-us/library/system.linq.expressions.aspx
System.Linq.Expressions.Expression
System.Linq.Expressions.BinaryExpression
System.Linq.Expressions.BlockExpression
System.Linq.Expressions.ConditionalExpression
System.Linq.Expressions.ConstantExpression
System.Linq.Expressions.DebugInfoExpression
System.Linq.Expressions.DefaultExpression
System.Linq.Expressions.DynamicExpression
System.Linq.Expressions.GotoExpression
System.Linq.Expressions.IndexExpression
System.Linq.Expressions.InvocationExpression
System.Linq.Expressions.LabelExpression
System.Linq.Expressions.LambdaExpression
System.Linq.Expressions.ListInitExpression
System.Linq.Expressions.LoopExpression
System.Linq.Expressions.MemberExpression
System.Linq.Expressions.MemberInitExpression
System.Linq.Expressions.MethodCallExpression
System.Linq.Expressions.NewArrayExpression
System.Linq.Expressions.NewExpression
System.Linq.Expressions.ParameterExpression
System.Linq.Expressions.RuntimeVariablesExpression
System.Linq.Expressions.SwitchExpression
System.Linq.Expressions.TryExpression
System.Linq.Expressions.TypeBinaryExpression
System.Linq.Expressions.UnaryExpression

Search HTML lines and remove lines that don't start with </form></td><td><a

I have an HTML file with very bad formatted code that I get from a website, I want to extract some very small pieces of information.
I am only interested in lines that start like this:
</form></td><td> <b>user897</b></td></tr><tr><td>HouseA</td><td>2</td><td class="entriesTableRow-gamename">HouseA Type12 <span class="entriesTableRow-moredetails"></span></td><td>1 of 2</td><td>user123</td><td>10</td><td>
and I want to extract 3 fields:
A:HouseA
B:HouseA Type12
C:user123
D:10
I know I've seen people recommend HTML Agility Pack and lib2xml but I really don't think I need all that. My app is in C/C++.
I am already using getline to start reading lines, I am just not sure what's the best way to proceed. Thanks!
std::ifstream data("Home.html");
std::string line;
while(std::getline(data,line))
{
linenum++;
std::stringstream lineStream(line);
std::string user;
if (strncmp(line.c_str(), "</form></td><td>",strlen("</form></td><td>")) == 0)
{
printf("found a wanted line in line:%d\n", linenum);
}
}
In the general case, an XML/HTML parser is likely the best way here, as it will be robust against differing input. (Whatever you do, don't use regexps!)
Update
However, if you're targetting specific input, as it seems that you're doing, you can use sscanf (as you suggest) or cin.read() or regexp to scan manually.
Just beware that this code can break at any moment that the HTML changes (even just with whitespace).
Therefore, my/our recommendation is to use a proper tool for the job. XML/HTML is not raw text, and should not be treated as such.
How about writing a python script instead? :)

How to replace strings in a code

I want to perform a batch replace operation on a project by following some rules. For e.g. I am taking notes in the code like this:
On every code piece, which is commented like this, I want to perform a replace operation, which will replace the input code piece with the output code piece in the following examples:
Input 1:
//+
a++;
//+(+SomeException$SomeMessage)
Output 1:
try
{
a++;
}
catch (AnException)
{
throw;
}
catch (Exception ex)
{
throw new SomeException("SomeMessage", "15", ex);
}
Input 2:
//+
a++;
//-(+InvalidOperationException$SomeMessage)
Output 2:
try
{
a++;
}
catch (InvalidOperationException ex)
{
throw new AnException("SomeMessage", "16", ex);
}
Input 3:
//+
a++;
//-(SomeMessage)
Output 3:
try
{
a++;
}
catch (Exception ex)
{
throw new AnException("SomeMessage", "17", ex);
}
The magic numbers (15, 16, 17) will increase for each code piece commented like this. I know this is not the best practice but I am not making the decisions and I am expected to handle exceptions like this, so I thought I can ease the pain by taking notes and batch replacing in the end. What is the best way to do this? Should I write my own code to perform replaces or is there some regex replace tool or something like that exist that can automatically make this for me?
Update: This is a one time job and my magic number has to be globally unique. So if it was 25 for the last match in a file, it must be 26 for the first match in the next file.
What is the best way to do this? Should I write my own code to perform replaces or is there some regex replace tool or something like that exist that can automatically make this for me?
I'd write a little program in C++ or C# to do this. There are presumably other tools and script languages that can do it; but given that it's a trivial job in C++ or C# and given that I aready know how to do it in these languages, why not?
I don't know what you mean by the "best" way, but for me at least this would be one of the easiest ways.
This looks like a simple language that you're going to compile into another language that looks like Java. A compiler is the right tool for a job like this, especially because you need to keep around the state of the current magic number. It also seems likely that whoever is making the decisions would want to add new features to the language, in which case a solution glued together with regular expressions might not work properly.
If I'm right about what you really want, your question is reduced to the problem of "How do I write a Domain Specific Language?" I'm not sure what the best method would be for this, but if you know Perl you could probably put together a solution with Parse::RecDescent.
I think it's possibly to do this with scripting and regular expressions, but this is the type of problem for which compilers were invented. If you end up making something hacky, God help the person that has to maintain it after you! :)
You could write a CodeSmith template that reads that input and outputs that output. But, I'm not sure you could do it in-line. That is, you would need a file of just inputs and then your template could give you the file of outputs. I'm not sure if that acceptable tho.
There's a lot of ways you could do this, even though you probably shouldn't (as you seem to realize, this will just result in meaningless exceptions). Nevertheless, here's a sed/sh combo to do the first one. It doesn't handle the autonumbering or your other variants. I'll leave that as an exercise for the OP.
P1='\/\/+'; P2='\(.*\)'; P3='\/\/+(+\([^$]*\)$\(.*\))';
echo 'foo()\n//+\na++\n//+(+SomeException$Message)'|sed ' /'$P1'/ { N; /'$P2'/ { N; /'$P3'/ { s/'$P1'\n'$P2'\n'$P3'/try\n{\n\t\1\n}\ncatch (AnException)\n{\n\tthrow;\n}\ncatch (Exception ex)\n{\n\tthrow new \2("\3", "0", ex);\n}/ } } } '
The echo is just a test string.
As an Emacs user, for a one time job I'd do this by defining keyboard macros,
then use set/increment/insert-register for the autonumbering magic. There
shouldn't really be any need for writing your own elisp functions.
Though if you need to perform this on more than just a couple of files, you'll
probably be better off writing a script to do the job.
If you do not happen to use an IDE like Emacs (as answered by many) with strong regex support I would write a little script. Note that text manipulation is in general more a scripting operation, e.g. Perl, Ruby, due to regex support in the language itself. On the other hand if you are very familiar with say Java Pattern, then writing it in Java is propably the fastest solution, even if you need more overhead esp. for a one time operation.
So a litte Ruby script might look like that (beware, I did not test it):
$cnt = 1
IO.readlines(filename).collect { |line|
if line =~ /^\s*\/\/\+\s*$/
$cnt += 1
["try\n", "{\n" ]
elsif line =~ /^\s*\/\/\+\(\+(.+)\$(.+)\)\s*/
["}\n", "catch (#{$1} ex)\n", "{\n",
"throw new AnException(\"#{$2}\", \"#{$cnt}\", ex);\n", "}\n"]
# propably more else for all cases
else
line
end
}.flatten
# save the file again