Pointer to one single char of a two dimensional array - c

As far as I know, an array like
int example[10]
Is nothing else than a pointer to the first element in this array.
char* argv[]
Is an array of pointers; so that should be pointers which point to other pointers.
I have following problem now:
int main(int argc, char* argv[])
{
double ptrarg2=argv[2][1];
printf("beginletter=%c\nbeginpos=%d\n",&ptrarg2, ptrarg2);
return 0;
}
I am starting the program with ./program test and expecting the output to be:
beginletter=c
beginpos=123213123
While 123213123 should be the adress where the c is actually stored.
I am actually getting:
beginletter=
beginpos=0
what am I doing wrong? Thank you in advance!

It looks like argv[0] is going to be "./program", argv[1] is going to be "test", and argv[2] is going to be undefined or NULL because you don't have three arguments. The value of argc should tell you how many items there are in argv[]. My guess in this case is that the answer will be 2, and therefore only the first two (argv[0] and argv[1]) are valid.
There are several other strange things going on here. ptrarg2 is declared as a double, not as a char; the behavior here would be to convert the character to its floating point numeric equivalent and store that. Perhaps you meant ptrarg2 to be a char?
Next up, the printf() doesn't correspond very well to its additional arguments. &ptrarg2 is a double *, but you're assigning it to a %c (character) field, not a %p (pointer) field. ptrarg2 is a double, but you're assigning it to a %d (decimal number) field, not a %lf (long float, aka double) field. printf will happily try and print out values even when your types don't match, but they will be wrong, and crashing is quite possible.

&ptrarg2 is the address of the local variable, which is not the address that you are expecting. Just use argv[1][0] and argv[1]. argv[1][0] will give you the first character of the first argument, and argv[1] will give you the pointer to the first argument.
#include <stdio.h>
int main(int argc, char* argv[])
{
printf("beginletter=%c\nbeginpos=%p\n",argv[1][0], argv[1]);
return 0;
}

Related

true properties of argv command line argument container

I understand that command line arguments are pointed by the string pointers in the argv [] array. i.e. argv [0] contains a pointer to the name of the program and argv [1] a pointer to the very first command line argument.
But I noticed a very different application of argv on the internet and is written below. I have compiled it successfully and it print out the second arguments third character.
#include <stdio.h>
int main(int argc , char *argv []) {
printf("%c\n", argv [1][2]);
return 0; }
I have two question arising from this use.
What is the true dimension of argv? does it stop at two or is there more?
I have noticed it the code that the programer has used %c to access and print the pointed content. Now, we can always parse a pointer (a string pointer) to %s and expect it to print out the set of chars untill null terminator.
upto the best of my understanding %c can only be used if the array it self contains the character.
i.e.
char yadhavan [] = yadhavan is a boy;
printf ("%c", yadhavan [3]);
Could someone please explain how %c has been used with a pointer array?
A little more explanation is always more than welcome!
argv is of type char*[] and holds several strings(command line arguments).
argv[i] is of type char* and holds a string.
argv[i][j] is of type char and holds a character.
What is the true dimension of argv? Does it stop at two or is there more?
It depends on how many command line arguments there are.
Could someone please explain how %c has been used with a pointer array?
One can declare char pointers and make them point to strings or just use a char array and hold the string:
char* str="string";
Or
char str[]="string";
In both of these ways it is possible to refer a character using:
printf("%c",str[3]);
argv is actually an array of char*. So, it is possible to refer a single character from it.
What is the true dimension of argv? does it stop at two or is there more?
argc tells you the argument count (or the dimension of argv as you put it). In other words, the number of strings in argv is equal to argc. So, argv can contain more than two strings if multiple arguments are provided. For example, if I were to execute some command like
$ foo file1 file2 ...
argv would look like
argv[0] = "foo\0"
argv[1] = "file1\0"
argv[2] = "file2\0"
...
See this other answer for more details on argc vs argv.
Could someone please explain how %c has been used with a pointer array?
First, %s is used for printing strings. %c is used for printing a single character. Second, argv is an array of strings, and a string is simply an array of characters (char). So, argv is really an array of arrays of chars. So, when you see
printf("%c\n", argv[1][2]);
the code is printing out the third character of the second argument in argv. So, if I were to execute the command
$ foo bar
argc and argv would look like
argc = 2
argv[0] = "foo\0"
argv[1] = "bar\0"
argv[1][0] = 'b'
argv[1][1] = 'a'
argv[1][2] = 'r'
argv[1][3] = '\0' // null terminator
char *argv [] is array of pointers and this acts as a two dimention array, it can't contains more than 2D. So the data in 'argv' is very similar to 2D, but limitations are not specified. You can check in the below link:Limit on the number of arguments to main in C
#include <stdio.h>
int main(int argc , char *argv []) {
printf("%c\n", argv [1][2]);
return 0; }
Here char *argv [] is very similar to
Char argv[][] //with no argument limitation.

Pointer to console arguments

As a C newbie, I have trouble to understand the following:
int main(int argc, char *argv[]) {
char **inputs = argv + 1;
char **inputs is a pointer to char *argv[] which is also a pointer, right? But why I have to add the "+1" at the end? Will this be an extra space for the '\0' character?
argv[0], or the first argument, is the string holding the name of your program.
argv[0] is the program you're currently running
argv[1+] are the arguments passed to the program
Perhaps not the best reference: https://www.gnu.org/software/gawk/manual/html_node/ARGC-and-ARGV.html
This is just to ignore the first entry which holds the path name that invoked the program. There is always at least one argument passed to main and this is it. Try passing some arguments yourself and print them..you'll get a better idea :)
To explain the "+1" in this context, we are doing pointer arithmetic. This is saying that you want the next memory address after whatever argv points to. Since argv points to the first address in an array of strings (char* in C), then the next memory address is guaranteed to be the second element in the sequence (arrays are laid out contiguously in memory). Thus, argv + 1 is equivalent to saying &argv[1].
As stated before, the first element in argv is just the program name. So you want everything after that for program inputs

pass char array as argument

Can anyone explain to me what I don't understand here please?
I am trying to pass the argument as a "string" (i know there are no strings in c) so that I can use that string later with other functions like it's a file name that has to be passed for example.
But I don't know why it won't accept it or what type should it be
#include <stdio.h>
int main ( int argc, char *argv[] )
{
char *array= argv[0];
foo(*array);
}
void foo( char *array)
// notice the return type - it's a pointer
{
printf(array);
}
thanks alot!
You should be calling the function like this:
foo(array);
What you're doing is dereferencing the pointer, which returns a char, which is the first character in the string.
Your printf call should also look like this:
printf("%s", array);
Your entire fixed code should look like the following:
#include <stdio.h>
void foo(char *array)
{
printf("%s", array);
}
int main ( int argc, char *argv[] )
{
// TODO: make sure argv[1] exists
char *array= argv[1];
foo(array);
}
When you say foo (*array), you're decaying the array into a pointer to the first element, in order to dereference that element, giving you the first character. That's what you're trying to pass to the function. Leave out the asterisk and just pass array for it to decay into the pointer you need.
The other issue is that you're not using printf correctly. First of all, here's a reference. You need to pass a string of tokens that tell the compiler what type of argument to expect next because it has no way of telling. In your case, your string would contain "%s" to tell it to expect a char *, and then you'd pass array as that char * argument.
printf ("The string is %s", array);
argv is a array of character pointers, that means argv is going to store the address of all the strings which you passed as command line argument.
so argv[0] will gives you the address of first string which you passed as command line argument, that you are storing into the pointer variable array in main function.
Now you have to pass only the address to the function foo but you are passing the first character of that string. For example if your first command line argument is temp.txt you are passing character t to the function foo. So inside foo function you are having a char pointer variable array, in that ASCII value of the character t will be assigned. And then you are passing that to printf, which will treads that ASCII value as address, and it will tries to access that address to print which will leads to crash (unexpected behaviour).
So you have to pass only the address of the command line argument to the function foo like below.
foo(array);
printf(array) - Here printf will treads the format specifier as string(%s) and it will tries to print all the characters starting from the address array untill it meets a null character \0.
But better to add the printf like below
printf("%s", array);

Accessing arguments with argv

This is something I've been testing by just printing out a bunch of stuff, but there's one case I can't quite figure out for some reason.
I need to pass an integer as an argument to a function to be used later, but when I print it back out again to make sure I stored it correctly, I get a random number. This is the relevant part of the code:
int num_bytes = argv[1];
....
printf("Max number of bytes: %d", num_bytes);
I only passed one argument to the function, which was an int. I also tried casting argv[1] as an int, but that didn't work either. I'm not sure if this is an issue with the printf or not. If it's just that, I don't mind. I just needed to know I stored the value as an int properly. I know that argv is an array of pointers to strings (C strings I think?) but I thought you could cast characters to ints.
char **argv is considered an array of characters (or a string). You'll need to convert the value inside of argv to an integer first.
You can do this through atoi:
int num_bytes = atoi(argv[1]);
argv is a pointer to an array of strings. You need to call atoi(argv[1]) to get the integer argument that you passed.

What does the ** operator mean in C?

Does ** have any special meaning in C?
Like this:
static intparse_one (int argc, char **argv)
{
cmd_line *slot;
int value;
Flag_name flag_name;
int i;
printf("argv %s\n",argv);
printf("argv[0] %c\n",**argv);
If so, does the line
**argv
make sense? A program I am trying to get to run is choking on it. If I try to print it I get a segmentation fault.
The first printf prints the string fine. The second printf fails.
Here is what I am getting for the output (The first line is correct):
argv -aps_instance1001-aps_ato0-aps_ipc_debug3
Segementation Fault (core dumped)
"Does ** have any special meaning in C?"
No, it is just two dereferences.
char **argv
means: argv dereferenced two times is a char. In other words argv is a pointer to a pointer to char.
The same for:
"If so, does the line: **argv make sense?"
The declaration says that **argv is a char. At runtime argv will be dereferenced two times; the value is the char that argv, the pointer to a pointer to char, is pointing to.
** is just two *.
As far as the segfault goes, look at your line printf("argv %s\n",argv);. The printf expects a char *, not char **, and so it's looking at an array of pointers rather than an array of characters. printf is trying to print everything at argv as a string of characters until it encounters a zero, and probably goes out of bounds before it finds one.
argv is a char **, which is a pointer to a pointer, or in this case an array of pointers. Don't print it directly, because it has no external meaning. (You can print the pointer value if you want to see it, of course.)
*argv or argv[0] is a char *, which is a pointer to char, which in this case is the first string in argv.
**argv is a char, which in this case is the first character of the first string in argv.
Yes.
char **argv
is the same thing as
char* argv[]
No.
Every * introduces a level of indirection. In this context, it means that argv is a pointer to a pointer. Which it is not, really, as technically you can see it a an array of pointers - it can be declared as char * argv[].
Obviously, by "no", I mean that ** is not special in itself. Or it is special, but neither more nor less than * or ***.
char **argv is same as char *argv[].
Here argv is the argument vector.
Isn't that a pointer to a pointer? I think the ** in front of the argv parameter has the same effect as ref in C#, in case you know C#.
While the string "**" does have a well defined meaning, I think the answer to the questions is "**" is not one operator, but two "*" in a row.
This is in contrast to Fortran where "**" is a single token and functions as the exponentiation operator.
So the meaning is well covered by Martin Beckett, but it really isn't "an operator".

Resources