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;
Related
I created a string in the main body and I want a function to access it. In order to access it I have to use the name of the string, not the pointer to it:
#include <stdio.h>
void test(char * s,char * b){
printf("%s\n",s);
//printf("%s\n",*s); this crashes it
printf("%c\n",*b);
}
int main(){
char s[]="string";
char b='b';
char * pointerb=&b;
char * pointerstring=&s;
test(pointerstring,pointerb);
}
Why is line 5 correct and not line 6?
printf("%s\n",*s);
%s is a format specifier for string. it expects pointer to array of char, but you are passing argument type is char. this is the reason for segmentation fault.
another side note, your has warning for this line
char * pointerstring=&s;
need to change to below.
char * pointerstring=s;
char* pointerstring now points to first char of string s[] which is nothing but 's'
Here is stack visualization of how pointer point to the string when program reaches at line char * pointerstring=s;
I have a function whose argument is const char *array[]
array[0] is the path, the rest are the arguments and it ends with NULL.
However, if I try to do execv(array[0], array) I get expected char * const* but argument is of type const char *
How do I go about this, and what is the difference between char * const* and const char *?
void start(const char *array[]) {
execv(array[0], array);
}
First, the error message is not copied correctly. If I run your code in GCC it shows this message instead (note the final *):
note: expected ‘char * const*’ but argument is of type ‘const char **’
which makes more sense as the message you show in the question, does not match the code you show. There is a mismatch in level or indirection.
That said, let's look at this part:
and what is the difference between char * const* and const char *?
Actually it is
and what is the difference between char * const* and const char **?
The first is a pointer to a const pointer to a char. The char that is pointed to is not const and might in theory be changed by execv.
The latter is a pointer to a pointer to a const char. This means, the char that is pointed to mustn't be modified. It might be some read-only string literal in ROM. If you pass such a pointer to a function that will try to modify it, it will fail in one way or the other. Therefore you are not allowed to pass a "pointer to const" to a function that does not expect it to be const.
That is what the compiler is telling you.
Now, how can you get rid of that warning...
To silence your compiler you could try to use some cast and cheat about real nature of that parameter.
In the end the problem will stay the same. A function trying to modify your read-only memory will not be working properly.
Instead you need to make a copy of your data:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
void start(const char *array[]) {
int i = 0;
// determine number of strings (including NULL)
while (array[i++] != NULL) ;
// Create an array able to hold pointers to copys
char *my_array[i];
// Copy strings into non-const memory
i = 0;
do
my_array[i] = array[i] ? strdup(array[i]) : NULL;
while (array[i++] != NULL);
execv(my_array[0], my_array);
// Free the memory for the copied strings
i = 0;
do
free(my_array[i]);
while (array[i++] != NULL);
}
int main(void)
{
const char *argv[] = {"ls", "ls", NULL};
start(argv);
return 0;
}
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];
I am trying get number ASCII for letter in char variable. My code so far is:
int main (int argc,char* argv[]) {
char c="A"; //here error
char b="'"; //here error
char d="z"; //and here error
printf("%d\n %d\n %d\n",c,b,d);
}
But I get the following errors:
analizer.c: In function ‘main’:
analizer.c:13:8: warning: initialization makes integer from pointer without a cast [enabled by default]
analizer.c:14:8: warning: initialization makes integer from pointer without a cast [enabled by default]
analizer.c:15:8: warning: initialization makes integer from pointer without a cast [enabled by default]
"A" is a string literal (an array of characters). 'A' is a character constant (an integer). What you want should be latter.
#include <stdio.h>
int main (int argc,char* argv[]) {
char c='A';
char b='\''; // use escape sequence
char d='z';
printf("%d\n %d\n %d\n",c,b,d);
}
The compiler will allow you to extract elements of the arrays (string literals) like below, but using character constants should be better in this case.
#include <stdio.h>
int main (int argc,char* argv[]) {
char c="A"[0]; // a typical way to deal with arrays
char b=*"'"; // dereferencing of a pointer converted from an array
char d=0["z"]; // a tricky way: this is equivalent to *((0) + ("z"))
printf("%d\n %d\n %d\n",c,b,d);
}
Basically you point to a string literal when you do this (which is invalid):
char c="A";
You need to write a single char to the variables:
char c='A';
char b='\'';
char b='z';
In C strings are just an array of characters which terminate with a \0. So if you want to use only one character, declare a char variable and use the character single quote. If you want to use a string, declare char array and use doublequote as
char a='A' // just one character
char b[20]="Some_Text"// multiple characters(a string)
In the first case, a contains the integer value of 'A' but in the second, b contains the base address of the string it points to. Each character in array b[] must be accessed with indexes as b[0] b[1] etc.
You can use strings to represent single characters as
char a[]="A" // a string of size 1
and then you can print it's integer equivalent as
printf("%d",a[0]); //0th element of the string
or
use the single quote method as described in other answers.
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]