Implementing "app.exe -instruction file" notation in C++ - c++

I have a project for my Data Structures class, which is a file compressor that works using Binary Trees and other stuff. We are required to "zip" and "unzip" any given file by using the following instructions in the command line:
For compressing: compressor.exe -zip file.whatever
For uncompressing: compressor.exe -unzip file.zip
We are programming in C++. I use the IDE Code::Blocks and compile using GCC in Windows.
My question is: How do you even implement that??!! How can you make your .exe receive those parameters in command line, and then execute them the way you want?
Also, anything special to have in mind if I want that implementation to compile in Linux?
Thanks for your help

You may want to look in your programming text for the signature of the main function, your program's entry point. That's where you'll be able to pull in those command line parameters.
I don't want to be more detailed than that because this is apparently a key point of the assignment, and if I ever find myself working with you, I'll expect you to be able to figure this sort of stuff out on your own once you've received an appropriate nudge. :)
Good luck!

As I recall, the Single UNIX Specification / POSIX defines getopt in unistd.h to handle the parsing of arguments for you. While this is a C function, it should also work in C++.
GNU GLIBC has this in addition to getopt_long (in getopt.h) to support GNU's extended --style .

Lo logré, I gotz it!!
I now have a basic understanding on how to use the argc and argv[ ] parameters on the main() function (I always wondered what they were good for...). For example, if I put in the command line:
compressor.exe -unzip file.zip
Then:
argc initializes in '3' (number of arguments in line)
argv[0] == "compressor.exe" (name of app.)
argv[1] == "-unzip"
argv[2] == "file.zip"
Greg (not 'Creg', sorry =P) and Bemrose, thank you guys for your help!! ^^

Related

QProcess Multiplatform command

I need to launch some script using QProcess.
For this, under windows, I use QProcess::execute("cmd [...]");.
However, this won't work if I go under some other OS such as Linux.
So, I was wondering if the best solution to make that code portable, would be to interfere with a mutliplatform scripting solution, such as TCL for exemple.
So I use : QProcess:execute("tclsh text.tcl"); and it works.
But, I got three questions concerning that problem. Because I'm not sure of what I've done.
Will execute() execute tclsh with the file test.tcl both under Windows and Linux wherever I execute it ? It seems to do so, but I want to be sure ! Is there any bad scenario that can happen ?
Is this a good solution ? I know lots of people have way more experience than I do, and I'd be grateful for anything I could learn !
Why not using std::system() ? Is it less portable ?
While this isn't a total answer, I can point out a few things.
In particular, tclsh is quite happy under Windows; it's a major supported platform. The main problem that could happen in practice is if you pass a filename with a space in it (this is distinctly more likely under Windows than on a Unix due to differences in community practice). However, the execute() as you have written it has no problems. Well, as long as tclsh is located on the PATH.
The other main option for integrating Tcl script execution with Qt is to link your program against the Tcl binary library and use that. Tcl's API is aimed at C, so it should be pretty simple to use from C++ (if a little clunky from a C++ perspective):
// This holds the description of the API
#include "tcl.h"
// Initialize the Tcl library; *call only once*
Tcl_FindExecutable(NULL);
// Make an evaluation context
Tcl_Interp *interp = Tcl_CreateInterp();
// Execute a script loaded from a file (or whatever)
int resultCode = Tcl_Eval(interp, "source test.tcl");
// Check if an error happened and print the error if it did
if (resultCode == TCL_ERROR) {
std::cerr << "ERROR: " << Tcl_GetString(Tcl_GetObjResult(interp)) << std::endl;
}
// Squelch the evaluation context
Tcl_DeleteInterp(interp);
I'm not a particularly great C++ coder, but this should give the idea. I have no idea about QProcess::execute() vs std::system().
A weak point of your solution is that on windows you'll have to install tclsh. There is no tclsh on Solaris either. May be somewhere else.
Compared to std::system(), QProcess gives you more control and information about the process of executing your command. If all you need is just to execute script (without receiving the output, for example) - std::system() is a good choice.
What I've used in a similar situation:
#ifdef Q_OS_WIN
mCommand = QString("cmd /C %1 %2").arg(command).arg(args);
#else
mCommand = QString("bash %1 %2").arg(command).arg(args);
#endif

stdout to a variable c/c++

I am using int res = system("uname -p"); in my c++ code.
It will give the the result in standard output by using
fprintf(stdout,"execution returned %d.\n",res);
I want to store this result string in a variable, I am unable to store it.
I google it but unable to find proper solution, Can any one tell me the correct way.
First, you don't need to run the uname command programmatically to get your processor. You can simply run the uname(2) syscall (which the uname command invokes). And you could also read and parse /proc/cpuinfo from your program.
If you wanted to read the output of some command, use popen(3) library function.
See also my answer to a related question.

Linux console commands in C++ (gcc compiler)

How can I give commands to Linux console (Ubuntu) from my c++ program, and assign a value, which my command tells, to string variable? Please, give me an example, in which program gives simple command "uname -a" to console and writes result.
Sorry for my bad English, I know it very little. I would be very happy, if someone will write his answer in Russian (if it allowed) . I was looking for the answer to my question in Russian resources, but found nothing, you're my last hope.
The command you need is popen. You can get information about it by typing man popen into your shell; if your Linux distribution runs its Russian translation, it should display the information about it in Russian.
Basically, popen just opens a "file" (stream), with which you can work just like with a regular file. Here's an example of how it could be used:
#include <stdio.h>
int main()
{
FILE *f;
char stuff[100];
f = popen("uname -a", "r");
fgets(stuff, 100, f);
printf("%s", stuff);
pclose(f);
}
The code above doesn't have any error handling; you should insert the appropriate checks after you read and understand the complete manual page (rus).
Look for Russian language resources that explain the popen(3) library routine. You will need to use popen to launch the command, then read the pipe to obtain the output.

Calling Mathematica from OCaml program

I am writing OCaml code. In part of it, I want to examine whether two arithmetic expression are equal (like x+2+y == x+2*y-y+2). Implemeting this in mathematica is straightforward, so all I want some help on executing Mathematica and get the result back in OCaml. My OS platform is Linux.
Cheers,
Z.
You may be able to use something along the lines of this:
let channel_to_mathematica, channel_from_mathematica = open_process "mathematica"
in
Printf.fprintf channel_to_mathematica "Tell me if this is equal ...\n";
let answer_from_mathematica = Scanf.fscanf channel_from_mathematica ...
in
...
Documentation of open_process here
Documentation of module Scanf here
A very general answer is to write a command-line Mathematica script that takes 2 expressions (either on the command line or stdin) and outputs whether they are equal.
Then in OCaml simply call that program with a system call.
As for writing such a command-line Mathematica script, I recommend MASH (disclosure: I made MASH):
Call a Mathematica program from the command line, with command-line args, stdin, stdout, and stderr

Executing a command from C++, What is expected in argv[0]?

I am using execv() to run commands from /bin/ such as 'ls', 'pwd', 'echo' from my c++ program, and I am wondering what value I should provide in argv[0];
const char * path = getPath();
char ** argv = getArgs();
execv(path,argv);
argv[0] is supposed to be the program name. It's passed to the program's main function. Some programs differentiate their behavior depending on what string argv[0] is. For example the GNU bash shell will disable some of its features if called using sh instead of bash. Best give it the same value that you pass to path.
In linux, argv[0] is the process name displayed by the top utility (which it probably gets from reading entries in /proc/)
argv[0] should be the full path of the command that you want to run.
I know that this is not the answer you're looking for but is there a specific reason why you're doing this? The reason I ask is that most if not all of the actions people normally run with either system() or execv() are available in libraries on either Windows or Unix and are safer, faster and less likely to suffer from circumstantial errors. By that I mean, for example, when the PATH changes and suddenly your code stops working.
If you're passing in a string, either in whole or in part, and running it then you also leave yourself open to a user gaining access to the system by entering a command that could be damaging. E.g. imagine you've implemented a file search using find /home -name and your user types in:
"%" -exec rm {} \;
Ouch!