making getopt() process argv[0] - c

I trying to emulate main() function like behavior for normal functions using string tokenizing and storing tokens in a NULL terminated char* array.
Every thing is fine except getopt(). It won't rearrange argv[0] coz it expects the first argument to be program name. But for my function the argv[0] isn't the program name. I want to make getopt() to also rearrange argv[0](non-option). How do I do that?

getopt(3) uses a global variable optind (option index) to track its progress through argv and initializes it to 1. Try setting optind = 0 before reading the options.

Try using
c = getopt(argc + 1, argv - 1, "xyz")
Edit: Which, as pointed out below, is a hack But I'd be interested to see a machine on which it didn't work.

Though the hack #Tom Tanner suggested worked for certain systems, it didn't compile for the target which I'm supposed to make it work. Another work around I found is to replace the first argument in my argv[] array with a dummy string and use getopt() with it.

Related

sscanf function in C

I'm working in my C program and I have a doubt about how to use the sscanf function.
I have to get from a string like something$HOME/something2 three strings: the first one has to contain "something", the second one "HOME" and the third one "/something2".
But also it has to be able to split $HOME or $HOME/something, or something$HOME...
What I wrote was something like that:
sscanf(str,"%m[^$]$%m[_a-zA-Z0-9]%*m", &ant, &act, &sig);
But for the cases $HOME, $HOME/something, something$HOME... it takes very strange strings. Any ideas of what can I put on my sscanf to get the other values by NULL in case they don't exist?
Sorry, but you should not use sscanf for that. Your input seems to be a shell command line argument and you seem to want implement variable expansion.
For that, you have to write your own parser that would parse the expression, identify and do variable expansion. It's not a job for scanf - it's a job for your custom loop where you inspect each and every character in a string.
There's a utility with like exactly that functionality called envsubst. You could inspect its source gettext/envsubst.c. You could also take a look at wordexp; however, wordexp function is a way broader function.

How to modify/use command line argument in main function if it is a string?

I want to compare the different elements of a command-line argument. It would be entered all together resulting in the string being found at argv[1]. However, I am not sure how to compare the elements and individual characters as I am looking for repetitions.
If I compared [2] to [3] in the string, there would be nothing there as only 1 string is entered in the command line argument and I need to compare the characters found within that string argv[1]. I am unable to include spaces so I wouldn't be able to compare argv[2] to argv[1].
Read Modern C and see this C reference.
If you code for Linux, read also documentation of GNU libc, in particular the section on parsing program arguments.
You could also use strcmp(3) to compare your program argument to some fixed constant string.
The program arguments are given to your main function, traditionally defined as int main(int argc, char**argv). They are always strings (of different addresses), and on POSIX you are practically certain that argc>0, argv[0] is a non-empty string (somehow the name of the program), all argv[i] with i >= 0 and i < argc are non-null, and argv[argc] is NULL.
You could code inside your main something like
if (argc>1 && !strcmp(argv[1], "foo")) {
/// handle `foo` as first program argument
}
I would recommend to study for inspiration the source code of GNU findutils or of GNU make.
I don't recommend modifying program arguments with e.g. some code like strcpy(argv[1], "bar"). It is not portable, perhaps forbidden, and certainly unreadable and brittle.
If you are on Linux, see also proc(5) about /proc/self/cmdline

Parsing command line arguments in c without spaces

I have a program that parses command line arguments using a while loop. Simply, while iterating through the length of argc, if an argument matches a flag than the next argument is taken as a variable. Now in my assignment we are asked to do this in a way that spaces between flags and integer arguments are optional.
For example if i input -k1 it is the same as -k 1 and 1 is the value stored.
I can't find anything that allows this. The only thing I can think is that if argc is an even number it means that there are no pals between a set of argument and i could use scanf("-k%d",key).
Any helpful pointers for me?
At a POSIX-compatible OS you can use a standart API for that: man getopt. It will do all the dirty job to parse the parameters and will provide you a convenient interface to deal with.
Here is a good example for it: http://www.gnu.org/software/libc/manual/html_node/Example-of-Getopt.html#Example-of-Getopt

transfer values between c and bash

Simple question, I hope
I have a c program that does a lot of math. It requires a few input floats and then returns a few floats. I would like this code to be incorporated into a bash script that runs it at the right time and passes it the right value, and then reads the result.
What is the simplest and easiest way to do this? Would passing these values as a command line argument at the calling of the c program work? And then simply store the results as a string in bash to be parsed at my convenience? Please tell me there is an easy way to do that!
Thanks
You can pass command line arguments to your C program, through arguments to main. In the easiest case, your program returns a single number (result) and you can capture that result back in your bash script:
#!/bin/sh
...
RESULT=$(mycprogram arg1 arg2)
...
You need to use
char * getenv (const char *name)
so you'll use something like
char *foo = NULL;
foo = getenv("BAR");
Keep in mind that you'll get a char* back, so if you're hoping for an int you'll need to use atoi() or something like it. Same goes for checking it's not NULL. If you're expecting many variables that you rely on, you could check for everything at the beginning of your program.

Why pass the program name as a parameter to main?

If I call:
./program hello world
then:
argc would be 3.
argv[0] would be "./program".
argv[1] would be "hello".
argv[2] would be "world".
What's the purpose of passing "./program" as an argument? In fact, it's not an argument at all!
You can make symbolic links to the same binary. Depending on what link you use, you will get different behaviour. Busybox is an example of this.
One use is so that the application can know how it was invoked (essentially, what its own name is).
Note that what appears in argv[] is implementation-defined. If you use one of the UNIX exec() functions, for instance, the contents can be whatever you like.
...and you can make make a nice help-function that display a help-text when invoked that doesn't need to be updated when the name of the executable changes.

Resources