I know basic c++ coding and command line syntax. Often, the main() function looks like this:
int main(int argc, char *argc[])
When I execute my program via command line, I just do this:
cd c:\path\to\foo 1
Where 1 is the argument. And of course, arc would be equal to '2' and the '1' would be at element '1' of the array argc (as opposed to 0).
I've seen the dash used in a lot of places. Specifically:
gcc -v
And if I type just 'gcc', it says there are no arguments. And if I type 'gcc v' I get "error: no such file or directory". But when I take a look at the minGW bin folder where gcc is, there is no folder 'v'.
This is just a style of setting options in programs. It comes from the getopt library provided in Unix/Linux etc. The -- form that kc7zax mentions in their answer is the long-form of these options (allowing a long identifier instead of a single character).
There's nothing magic about these. They are simply parsed out of the argv array. You can implement similar or identical functionality yourself if you want. But it's a pain. That's why libraries exist.
It is simply a standard for identifying the name of a command line parameter from the parameter value that may exist. e.g. gcc -o myfile.o
The windows world usually sees a - or a / as the marker. I've often encountered a -- in the unix/bsd world as well.
Related
So I'm trying to build a version of wc, and one of the key abilities of this program is that you can specify files in two ways:
wc file.txt
and
wc < file.txt
I have figured out how to implement the first way, but I am struggling with the second way. How could I approach this?
The way tools like this work, which includes many others like grep, is if there's no arguments on the command-line that specify file-names, input is read from std::cin.
In a simple sense, if argc is 1 then you have only the executable name as an argument so no files were specified. In a more practical situation you'd use something like an argument parser which may interpret various flags, but which will give a count of non-flag arguments.
This question already has answers here:
Reading command line parameters
(4 answers)
Closed 9 years ago.
When you right click on a program in windows(such as starcraft.exe) and look at its properties there is a text field called "target" which contains the full path of the binary. I have seen programs able to parse flags added to the target such as "C:\programfiles\myprogram\myprogram.exe -x 1280 -y 360" and the program would start up in the specified resolution. My question is how to read those arguments, if it is done by argv[] please just inform me of my stupidity.
C++ is the language, VS express 2012 desktop is the environment.
you receive those parameters when calling executable main method int main(int argc, char* argv[]) as argc (count) and argv[] parameters all you have to do is just parse them
here is an example How to parse command line parameters
You'll want to avoid comparisons between char* and string literals without strncmp.
Remember that argc is the the argument count (including the program name).
argv is an array of C strings specifying the arguments (first being the program name as invoked).
In this case, you're usually best off using a library, like getopt. This will make interleaved options, long options, and arguments much more sane to manage (assuming order between options and arguments is largely unimportant).
Similar question to Linux equivalent of GetCommandLine and CommandLineToArgv
Is it possible to get the raw command line in linux? The file /proc/self/cmdline is destroyd.
./a.out files="file 1","file 2" param="2"
prints
./a.outfiles=file 1,file 2param=2
which is junk
Escaping command line does work for all arguments but the first.
./a.out files=\"fil 1\",\"fil 2\"\ param=\"2\"
prints
./a.outfiles="fil1","fil2" param="2"
You can't do that. The command line arguments are actually passed to the new process as individual strings. See the linux kernel source:
kernel_execve
Note that kernel_execve(...) takes a const char *argv[] - so there is no such thing as a long string commandline in Linux - it's the layer above that needs to split the arguments into separate components.
Edit: actually, the system call is here:
excve system call
But the statement above still applies. The parameter for argv is already split by the time the kernel gets it from the C-library call to exec.
It is the responsibility of the "starter of the program" (typically a shell, but doesn't have to be) to produce the argv[] array. It will do the "globbing" (expansion of wildcard filenames to the actual files that it matches) and stripping of quotations, variable replacement and so on.
I would also point out that although there are several variants of "exec" in the C library, there is only one way into the kernel. All variants end up in the execve system call that I linked to above. The other variants are simply because the caller may not fancy splitting arguments into invdividual elements, so the C library "helps out" by doing that for the programmer. Similarly for passing an environment array to the new program - if the programmer don't need specific environment, he/she can just call the variant that automatically take the parent process env.
There is an abnormality in the value of argc when '*' is passed as one of the arguments calling a program in c.
I made a simple code in c and saved it as 'test2.c'.Here is the following code of 'test2.c'---
#include<stdio.h>
#include<stdlib.h>
int main(int argc,char* argv[])
{
printf("%d\n",argc);return 0;
}
I compiled it and call it as--
dev#ubuntu:~$ gcc test2.c -o t
dev#ubuntu:~$ ./t *
31
So, i am getting the argument count value as 31; whereas if '*' is replaced by any other binary operator ; the value of argc is 2(which is also logically correct).
dev#ubuntu:~$ ./t +
2
I am not able to fathom why is it so....and there is one more interesting thing.when '-' is used in place of '';the answer is 2(which is again logically correct)
dev#ubuntu:~$ ./t -*
2
Can anyone help me in this;thanks in advance.
Its just the shell expansion. The shell will expand * to the filenames (directories included) in the current directory in which the program is executing.
+ or ; does not have special interpretations therefore they are considered as normal strings, but * has special interpretation, thus it is expanded to the list of all files in current directory, which is passed to your program.
Try using
./t '*' or ./t \*
This stops special interpretation of *. The first one used the bash (looks like you are in bash) single quote, which does not make any special interpretation inside the patterns in the quote, and the next one uses escape sequence.
It's the shell that expands * to the list of files in the current directory. Print out the argv to see that this is the case.
argc will always give you the number of elements in argv[].
The arguments passed to argv[] will always contain at least the name of the executable so argc is always the number of arguments + 1.
The * case is although special, since your shell will expand * to all files and directories within your local directory. If you want * to not be expanded pass it as "*" with the double-quotes.
Try echo * vs echo "*" in your shell to see how * gets expanded.
This is just the shell expanding the star operator * to the current directory from where you are executing this program.
There are several expansions performed before the shell initiates execution, for example ~ (tilde), {} (braces) and $ (parameters), of course depending on your operating system. You can find the GNU list of expansions in the link below.
GNU BASH Manual - 3.5.3 Shell Parameter Expansion
Tip: If you had printed the values of your arguments you would probably see a list of directories and files, and the argument count 'argc' would change depending on which directory you execute from.
If I have this:
int main(int argc, char *argv[])
In the body, you can sometimes find programs using argv[1].
When do we use argv[1] over argv[0]? Is it only when we just want to read the second argument in the command line?
By convention, argv[0] is the current program's name (or path), and argv[1] through argv[argc - 1] are the command-line arguments that the user provides.
However, this doesn't have to be true -- programs can OS-specific functions to bypass this requirement, and this happens often enough that you should be aware of it. (I'm not sure if there's much you can do even if you're aware of it, though...)
Example:
gcc -O3 -o temp.o "My file.c"
would (should) produce the following arguments:
argc: 5
argv: ["gcc", "-O3", "-o", "temp.o", "My file.c"]
So saying argv[0] would refer to gcc, not to -O3.
argv is an array of pointers, and each pointer in this array stores one argument from command line. So argv[0] is the first argument (that is the executable/program itself), argv[1] is the second argument, and so on!
The total number of arguments is determined by argc.
argv[0] is the execution path of the program, argv[1] is the first parameter to the program
Let's suppose your C++ executable file is:
/home/user/program (or C:\program.exe in Windows)
if you execute:
./home/user/program 1 2 (or C:\program.exe 1 2 in Windows)
argv[0] = /home/user/program (C:\program.exe)
argv[1] = 1
argv[2] = 2
That is because:
argv[0] is the path of the executable file
argv[1] is the 1st argument
Edit:
Now I see that argv[0] isn't necessarily the path of the executable file.
Read the following SO question: Is args[0] guaranteed to be the path of execution?
Short answer is yes, the array contains all the options passed into the program.
as argv[0] is filepath of the program itself.
Extra command line parameters are in further indexes, argv[1],argv[2]..
You can read more here :
http://www.site.uottawa.ca/~lucia/courses/2131-05/labs/Lab3/CommandLineArguments.html
Yes, that's mostly it, argv[1] is the second command line parameter. The first command line parameter is the name of the program itself.
Alternatively, to avoid the semantic mess that this answer originally had, and the comments from others, it might make sense to call argv[0] the zeroth parameter, so that argv[1] would now be the "first" of the user supplied values.
In any event, this comes from the exec() family of functions, e.g. execl which has usage:
int execl(const char *path, const char *arg0, ... /*, (char *)0 */);
In the (Unix) shell when you type in a command, if necessary the shell first resolves the command name (using $PATH) to find the real absolute path. The (absolute or relative) path is supplied for path, and the command as originally typed-in is supplied as arg0, eventually becoming argv[0] in your program.
The remaining command line parameters then end up as argv[1], etc.