I pass a character to my program and I want to store this character to variable. For example I run my program like this ./a.out s file. Now I want to save the argv[1] (its the s) to a variable (lets say I define it like this char ch;. I saw this approach:
ch = argv[1][0];
and it works. But I cant understand it. The array argv isnt a one dimensional array? if i remove the [0], I get a warning warning: assignment makes integer from pointer without a cast
If you look at the declaration of main() you see that it's
int main(int argc, const char **argv);
or
int main(int argc, const char *argv[]);
So argv is an array of const char * (i.e. character pointers or "C strings"). If you dereference argv[1] you'll get:
"s"
or:
{ 's' , '\0' }
and if you dereference argv[1][0], you'll get:
's'
As a side note, there is no need to copy that character from argv[1], you could simply do:
const char *myarg = NULL;
int main(int argc, const char **argv) {
if (argc != 2) {
fprintf(stderr, "usage: myprog myarg\n");
return 1;
} else if (strlen(argv[1]) != 1) {
fprintf(stderr, "Invalid argument '%s'\n", argv[1]);
return 2;
}
myarg = argv[1];
// Use argument as myarg[0] from now on
}
argv is an array of strings, or say, an array of char *. So the type of argv[1] is char *, and the type of argv[1][0] is char.
The typical declaration for argv is
char* argv[]
That is an array of char*. Now char* itself is, here, a pointer to a null-terminated array of char.
So, argv[1] is of type char*, which is an array. So you need another application of the [] operator to get an element of that array, of type char.
Lets see mains' signature:
int main(int argc, char *argv[])
No, argv is not a one-dimensional array. Its is a two-dimensional char array.
argv[1] returns char*
argv[1][0] returns the first char in in argv[1]
Related
I have this code:
#include<stdio.h>
int main(int args,char*argv[])
{
char *input_f;
input_f=(argv+1);
printf("%d\n",input_f);
printf("%d\n",(argv+1));
printf("%s\n",*(argv+1));
printf("%s\n",argv[1]);
printf("%s\n",*input_f);
return 0;
}
But if I run it (test.exe hi.txt) the output will be:
1577880
1577880
hi.txt
hi.txt
(null)
How can I create pointer to point the argv[1]?
And why my code doesn't work?
EDIT: The program takes an file at input and the pointer input_f points it but at the output the argv[1] prints the file name but input_f doesn't!
Use this
input_f=*(argv+1);
instead of
input_f=(argv+1);
and
use this
printf("%s\n", input_f);
instead of
printf("%s\n",*input_f);
Full code:
#include<stdio.h>
int main(int args,char*argv[])
{
char *input_f;
input_f=*(argv+1);
printf("%s\n",input_f);
printf("%s\n",*(argv+1));
printf("%s\n",argv[1]);
printf("%s\n",input_f);
return 0;
}
why my code doesn't work?
Assuming that input_f is declared as:
char *input_f;
the format specifier %s in the printf():
printf("%s\n",*input_f);
expects that given argument is of type char *, you are providing *input_f, which is of type char.
How can I create pointer to point the argv[1]?
argv is of type array of pointer to char. Therefore, argv[1] is of type pointer to char. So, you can store it address in a pointer to pointer to char, i.e.: type char **:
char **p = &argv[1];
This question already has answers here:
C difference between *[] and **
(8 answers)
Closed 2 years ago.
CODE 1
#include<stdio.h>
int main(int argc, char *argv[])
{
int j;
printf("%d", argv[1][0]);
return 0;
}
CODE 2
#include<stdio.h>
int main(int argc, char **argv)
{
int j;
printf("%d", argv[1][0]);
return 0;
}
CODE 1 and CODE 2 both give same output. but argument 2 of main function in CODE 1 and CODE 2 are different. Array of pointers are created above data section at compile time. argv is array of pointers. Then we should declare argument in main function as pointer to pointer to character i.e., **argv. How it is correct to declare as in CODE 1?
It is fundamental to c that char** x and char* x[] are two ways of expressing the same thing. Both declare that the parameter receives a pointer to an array of pointers. Recall that you can always write:
char *parray[100];
char **x;
x = &parray[0];
and then use x identically.
Basically, char* argv[] means array of char pointers, whereas char** argv means pointer to a char pointer.
In any array, the name of the array is a pointer to first element of the array, that is, it contains the address of the first element.
So in the code given below, in char array x, x is a pointer to first element, '1', which is a character. So it's pointer to a character.
And in array arr, arr is pointer first element, x, which is itself a pointer to a character. So it a pointer to another pointer.
Hence, x is char*, and arr is char**.
While receiving something in a function, basic rule is that, you have to tell the type of the thing you are receiving. So either you simply say that you want to receive a char**, or you can also say char* arr[].
In first case, we don't need to think anything complex. We simply know, we are receiving an array of char*. Don't we know this? So, we receive it, and use it.
In second case, it is simple, as i have explained above that arr is a char**, you can put this as it's type and receive it safely. Now the system knows the type of the stuff we have received, we can access next elements by simply using array annotation. It's like, we have received the starting address of the array, we can surely go to the next elements, and as we know it's type, we know what it contains and how we can use that further. We know it contains pointer to char, so we can legally access them as well.
void func1(char* arr[])
{
//function body
}
void func2(char** arr)
{
//function body
}
int main()
{
//x, y and z are pointer to char
char x[3]={'1', '2', '3'};
char y[3]={'4', '5', '6'};
char z[3]={'7', '8', '9'};
//arr is pointer to char pointer
char* arr[3]={x, y, z};
func1(arr);
func2(arr);
}
They're exactly the same. §5.1.2.2.2 of the C11 standard states:
The function called at program startup is named main. The
implementation declares no prototype for this function. It shall be
defined with a return type of int and with no parameters:
int main(void) { /* ... */ }
or with two parameters (referred to here as argc and argv, though
any names may be used, as they are local to the function in which they
are declared):
int main(int argc, char *argv[]) { /* ... */ }
or equivalent;10) or in some other implementation-defined
manner.
10) Thus, int can be replaced by a typedef name defined as int, or
the type of argv can be written as char ** argv, and so on.
Clearly the intent is for both declarations to be identical. On top of that, the rule is described in §6.7.6.3/7:
A declaration of a parameter as ‘‘array of type’’ shall be adjusted
to ‘‘qualified pointer to
type’’, where the type qualifiers (if any) are those specified within the [ and ] of the array type derivation. ...
[EDIT] Using GCC at the time of the comment probably GCC 7.2
declaring an array like this
char array[]
makes it const which means that you CAN'T have the following code
char array[] = "hello";
array = "hey";
even though the second string is smaller and should fit you get this error
error: array type 'char [6]' is not assignable
if you have **argv you can write
main(int argc, char **argv)
{
char **other_array;
/*
* do stuff with other_array
*/
argv = other_array;
}
if you have *argv[] then
main(int argc, char *argv[])
{
char **other_array;
/*
* do stuff with other_array
*/
argv = other_array;
}
gives you this warning
warning: assigning to 'const char **' from 'char **' discards qualifiers in nested pointer types
so it is technically a small optimisation as if you had written const
I have this C function:
void sysexCallback(byte command, byte argc, byte *argv)
{
...
}
and I want to convert argv[0] (binary) to simple string. I tried things like:
char v[10];
strcpy(v,argv[0]);
But that gives me an error:
Arduino/hardware/tools/avr/avr/include/string.h:126:14: error: initializing argument 2 of 'char* strcpy(char*, const char*)' [-fpermissive]
strcpy takes two character pointers as its parameters. argv[0] is a byte, not a char pointer. Try
strcpy(v,(char *)argv);
Alternatively you can make a character pointer and point it to the byte pointer like so:
char *string = (char *)argv;
I am quite new with C.
#include <string.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
char* c=argv[1];
for (int i=0;i<sizeof(c);i++)
{
printf("%c\n",c[i]);
}
return 0;
}
I am trying to write a program to print every character of a word.
When I try with test: It displays
t
e
s
t
When I try with testtesttest: It displays:
t
e
s
t
I don't understand why, can you tell me why please?
Two problems: Using the sizeof operator on a pointer returns the size of the pointer and not what it points to. If you want the length of a string you should use strlen.
The second problem is what will happen if there are no arguments to your program. Then argv[1] will be NULL.
sizeof(c) is the memory size used by c, which is a char*, that is, a pointer on a char. This type takes 4 bytes of memory, hence the t e s t (4 chars). What you want is strlen, which gives you the length of a string.
#include <string.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
char* c=argv[1];
int length = strlen(c);
for (int i=0;i<length;i++)
{
printf("%c\n",c[i]);
}
return 0;
}
You should also test that your program gets at least one argument. argc is the length of argv, so you need to ensure that argc > 1.
sizeof operator returns the size of the type of operand. c is of type char *, therefore sizeof(c) will return the size of char * instead of the string. You should use strlen(c).
I am still trying to understand about doublepointers.
I do know how double pointers are usually used in most cases like
void foo(char **ptr)
{
// blah
}
int main(void)
{
char *ptr;
foo(&ptr);
}
However i have no idea what one does differently than the other
int main(int argc, char **argv) //Double pointer
int main(int argc, char *argv[]) // Single
When used as a parameter to a function, an array designator [] is exactly the same as a pointer. The two declarations you have for main are in fact identical.
There are times when the two different syntaxes mean different things, but this isn't one of them.
In this case it means you have an array of pointers. Each pointer points to an array of characters. argv[0] is a pointer to the first char* string, argv[1] is a pointer to the second char* string, etc.
I feel your pain! It took me a long time to convince myself that I should treat them exactly the same.
argv[1] points to the first parameter, argv[argc-1] points to the final parameter. Yes, all you sharpshooters, that's true iff argc > 0.
That's my formula and I'm stickin' to it.