pointer assignment to const char*[] in c - c

I'd like to assign a pointer to a const char* array like this:
#include <stdio.h>
const char *keyContainer[2]= {"test", "test2" };
const char *keyPtr = &keyContainer;
int main(void)
{
printf("%s\n", keyPtr[0]); //test
printf("%s\n", keyPtr[1]); //test2
return 0;
}
keyPtr contains the address of keyContainer but I can't get access to the content of keyContainer.

When you use this, you get the warning "Initialization from incompatible pointer type [enabled by default]", and that's because keyContainer is char *[2], which we will say can be similar (not the same !) as char **. So you need to use const char **keyPtr = keyContainer;.
For example :
#include <stdio.h>
const char *keyContainer[2]= {"test", "test2" };
const char **keyPtr = keyContainer;
int main(void)
{
printf("%s\n", keyPtr[0]);
printf("%s\n", keyPtr[1]);
return 0;
}
Hope this helps !

Related

Julia retrieve global variable in C

I want to retrieve global variable x I just set in Julia from my C application.
Here's the code I have so far:
#include <julia.h>
void SimpleExecute(char *command, char *resultVar, char* result) {
jl_eval_string(command);
jl_value_t *var = jl_get_global(jl_base_module, jl_symbol(resultVar));
const char *str = jl_string_ptr(var);
sprintf(result, "%s", str);
}
int main(int argc, char *argv[])
{
char* result = malloc(sizeof(char) * 1024);
jl_init();
//(void)jl_eval_string("println(sqrt(2.0))"); //works
(void)SimpleExecute("x=sqrt(2.0)", "x", result);
jl_atexit_hook(0);
return 0;
}
However debugger shows that var is still NULL after jl_get_global call. Why?
I followed this tutorial but it does not touch on arbitrary variable retrieval. Source code shows similar usage.
I think there are a few things going on here:
First, you need to use jl_main_module and not jl_base_module.
Second, you cannot use jl_string_ptr to get the string value of a integer or floating point value. You can either use x=string(sqrt(2.0)) as the command to run, or use jl_unbox_float64 as a function to unbox the value you get back from Julia.
#include <julia.h>
#include <stdio.h>
void SimpleExecute(char *command, char *resultVar, const char* result) {
jl_eval_string(command);
jl_value_t *var = jl_get_global(jl_main_module, jl_symbol(resultVar));
if (var && jl_is_string(var)) {
const char * str = jl_string_ptr(var);
printf("%s\n", str);
} else {
const double val = jl_unbox_float64(var);
printf("%f\n", val);
}
}
int main(int argc, char *argv[])
{
char* result = malloc(sizeof(char) * 1024);
jl_init();
// (void)jl_eval_string("println(sqrt(2.0))"); //works
(void)SimpleExecute("x = sqrt(2.0)", "x", result);
jl_atexit_hook(0);
return 0;
}
You can run this by modifying the following:
cc -I/Users/$USER/Applications/Julia-1.3.app/Contents/Resources/julia/include/julia/ -Wl,-rpath,/Users/$USER/Applications/Julia-1.3.app/Contents/Resources/julia/lib/ -L/Users/$USER/Applications/Julia-1.3.app/Contents/Resources/julia/lib/ -ljulia main.c -o main

How to convert properly char * const[256] to const char * const*

I have this struct:
typedef struct cmdLine {
char * const arguments[256];
} cmdLine;
I also have an argument cmdLine *pCmdLine. I want to use execvso I write execv((pCmdLine->arguments[0]), pCmdLine->arguments);. The second argument doesn't feet properly to execvand I want to ask how to convert it properly.
The warning I get is: Passing 'char* const[256]'' to parameter of type 'const char *const *' discards qualifiers in nested pointer types. I would lie for some help to convert it properly, thanks.
I do not see any problems:
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdio.h>
struct
{
char * const arr[20];
}*str;
void foo(char *const par[])
{
volatile const char * const ptr = par[4];
printf("%s\n", par[7]);
printf("%s\n", ptr);
}
void foo1()
{
foo(str -> arr);
}
https://godbolt.org/z/4Sv4a8

How to pass 2d array of string to the function and print value of it?

Why it is not working... It should be working, right? gcc have problem with this line, but why?
render_history(history, 2);
Sorry for bothering. I am just a beginner.
#include <stdio.h>
void render_history(char** history, const int entry);
int main()
{
char* history[3][4];
history[0][0] = "1234";
history[1][0] = "5678";
history[2][0] = "9012";
render_history(history, 2); //??
return 0;
}
void render_history(char** history, const int entry)
{
// print "9012"
}
gcc have problem with this line, but why?
Because the type is wrong. char* history[3][4]; can't be passed as char**. They are incompatible types.
Try something like:
#include <stdio.h>
void render_history(char* (*history)[4] , const int entry)
{
printf("%s\n", history[entry][0]);
}
int main()
{
char* history[3][4];
history[0][0] = "1234";
history[1][0] = "5678";
history[2][0] = "9012";
render_history(history, 2);
return 0;
}
As mentioned above double pointer not equal to 2D array.
You can also use pointer to pointer of char. char **history. And with this you have several option:
1) Use compound literals
#include <stdio.h>
void render_history(const char **history, const int entry)
{
printf("%s\n", history[entry]);
}
int main(void)
{
const char **history = (const char *[]) { "1234", "5678", "9012", NULL};
render_history(history, 2);
return 0;
}
If you need change your data later
2) Use dynamic memory allocation with malloc
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void render_history(char **history, const int entry)
{
printf("%s\n", history[entry]);
}
int main(void)
{
char **history = malloc(3 * sizeof(char *));
for (int i = 0; i < 3; ++i)
{
history[i] = malloc(4 * sizeof(char));
}
strcpy(history[0], "1234");
strcpy(history[1], "5678");
strcpy(history[2], "9012");
history[3] = NULL;
render_history(history, 2);
return 0;
}
If you use 2nd option dont forget free memory after use.

C - Pass Array of Strings as Function Parameter

I need to pass a pre-allocated array of strings as a function parameter, and strcpy() to each of the strings within the string array, as in this example:
static void string_copy(char * pointer[]) {
strcpy(pointer[0], "Hello ");
strcpy(pointer[1], "world");
}
int main(int argc, const char * argv[]) {
char my_array[10][100];
string_copy(my_array);
printf("%s%s\n", my_array[0], my_array[1]);
}
And the resulting printed string would be 'Hello world'.
How do I pass a pre-allocated string array and fill out each string within a function as shown above?
When you are doing string_copy(my_array), you are passing a char (*)[100], i.e. pointer to char[100] array to your function. But your function is expecting a char *[], i.e. array of char pointers, because you have defined your function that way.
You can fix this by making changes so that your function (string_copy()) expects a char (*)[100], instead of a char *[].
For this, you can change your function definition as:
/* Your my_array gets converted to pointer to char[100]
so, you need to change your function parameter
from `char *pointer[]` to `char (*pointer)[100]`
*/
/* static void string_copy(char *pointer []) */
static void string_copy(char (*pointer) [100])
{
strcpy(pointer[0], "Hello ");
strcpy(pointer[1], "world");
}
* Alternative Solution *
A different design/solution would be to change in your main() function so that you are actually passing a char *[], which decays into a char ** - which is fine - to string_copy(). This way you would NOT have to change your string_copy() function.
int main(int argc, const char * argv[]) {
char my_array[10][100];
int tot_char_arrs, i;
char *char_arr_ptr[10];
/* Get total number of char arrays in my_array */
tot_char_arrs = sizeof(my_array) / sizeof(my_array[0]);
// Store all char *
for (i = 0; i < tot_char_arrs; i++)
char_arr_ptr[i] = my_array[i];
/* Actually passing a char *[].
it will decay into char **, which is fine
*/
string_copy(char_arr_ptr);
printf("%s%s\n", my_array[0], my_array[1]);
}
you need to use a pointer to the array. here is an example with 1 dimension array:
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
static void string_copy(char **pointer) {
strcpy(pointer[0], "Hello ");
}
int main(int argc, const char * argv[]) {
char my_array[10];
char * p_array = my_array;
string_copy(&p_array);
printf("%s\n", my_array);
}
Your function can simply accept matrix dimensions and pass a const char * that stores the array of literals (pre-allocated) strings:
#include <stdio.h>
#include <string.h>
#define STRINGS_LENGTH 100
static void string_copy(size_t n, size_t m, char pointer[n][m], const char *strings_to_copy[])
{
for (size_t i=0; i< n; i++)
{
strcpy(pointer[i], strings_to_copy[i]);
}
}
int main( void )
{
const char *strings[] = { "hello", "World" };
char my_array[sizeof(strings)/sizeof(strings[0])][STRINGS_LENGTH];
string_copy(sizeof(strings)/sizeof(strings[0]), STRINGS_LENGTH, my_array, strings);
printf("%s %s\n", my_array[0], my_array[1]);
}
You can also change the structure of your code using dynamic allocation for your output array like:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
static bool string_copy(char *pointer[], const char *strings_to_copy[], size_t strings)
{
for (size_t i=0; i< strings; i++)
{
pointer[i] = malloc(strlen(strings_to_copy[i])+1);
if (pointer[i] != NULL)
strcpy(pointer[i], strings_to_copy[i]);
else
return false;
}
return true;
}
int main(void)
{
const char *strings[] = { "hello", "World" };
char *my_array[sizeof(strings)/sizeof(strings[0])] = {0};
if (string_copy(my_array, strings, sizeof(strings)/sizeof(strings[0])) )
{
printf("%s %s\n", my_array[0], my_array[1]);
}
for (size_t i = 0; i<sizeof(strings)/sizeof(strings[0]); i++)
free (my_array[i]);
}

char pointer not returning proper value

In below code ptr prints "hello world" but temp is blank though I am passing temp as address.What can be possible reasons?
#include <stdio.h>
#include <string.h>
#include <malloc.h
unsigned char temp[1024];
void func(unsigned char *ptr)
{
const char* x = "hello world";
ptr = (unsigned char*) x;
printf("ptr=%s\n",ptr);
}
int main ()
{
func(temp);
printf("temp=%s\n",temp);
return 0;
}
This is due to the shadow parameter passing used in C.
On the inside of func, you are changing a local shadow of temp and making it point to "hello world" interned string. This does not change the original pointer temp in main context.
In order to change temp you must pass a pointer to temp in and adjust it:
#include <stdio.h>
#include <stdlib.h>
void func(unsigned char **ptr)
{
const char *x = "hello world";
*ptr = (unsigned char*) x;
}
int main ()
{
unsigned char *temp;
func(&temp);
printf("temp=%s\n",temp);
return 0;
}

Resources