I have a struct that contains a field named void * user_data.
Here is the library declaration:
typedef struct esp_http_client_event {
esp_http_client_event_id_t event_id;
esp_http_client_handle_t client;
void *data;
int data_len;
void *user_data;
char *header_key;
char *header_value;
} esp_http_client_event_t;
When I declare the struct, I assign a buffer to user_data:
char g_http_response_buffer[MAX_HTTP_OUTPUT_BUFFER] = { 0 };
...
esp_http_client_config_t config = {
.url = WEB_URL,
.event_handler = client_event_handler,
.transport_type = HTTP_TRANSPORT_OVER_SSL,
.crt_bundle_attach = esp_crt_bundle_attach,
.buffer_size_tx = 1024,
.user_data = g_http_response_buffer,
};
After that, I want to manipulate g_http_response_buffer by using the structure, passed to a function (the function is a callback, but I don't think it's relevant).
Inside the function, I use it in the following way:
esp_err_t
client_event_handler (esp_http_client_event_handle_t evt)
{
static int output_len = 0;
esp_err_t ret = ESP_OK;
switch (evt->event_id)
{
case HTTP_EVENT_ERROR:
ESP_LOGI(g_p_tag, "HTTP_EVENT_ERROR");
break;
case HTTP_EVENT_ON_CONNECTED:
ESP_LOGI(g_p_tag, "HTTP_EVENT_ON_CONNECTED");
break;
case HTTP_EVENT_HEADER_SENT:
ESP_LOGI(g_p_tag, "HTTP_EVENT_HEADER_SENT");
break;
case HTTP_EVENT_ON_HEADER:
ESP_LOGI(g_p_tag, "HTTP_EVENT_ON_HEADER, key=%s, value=%s",
evt->header_key, evt->header_value);
break;
case HTTP_EVENT_ON_DATA:
ESP_LOGI(g_p_tag, "HTTP_EVENT_ON_DATA, len=%d", evt->data_len);
if (!esp_http_client_is_chunked_response(evt->client))
{
if (evt->user_data)
{
memcpy(evt->user_data + output_len, evt->data,
evt->data_len);
ESP_LOGI(g_p_tag, "Dati non chunk: %s",
(char *) evt->user_data);
}
if (ESP_OK == ret)
{
output_len += evt->data_len;
}
}
else
{
if (evt->user_data)
{
memcpy(evt->user_data + output_len, evt->data,
evt->data_len);
ESP_LOGI(g_p_tag, "Dati chunk: %s",
(char *) evt->user_data);
}
if (ESP_OK == ret)
{
output_len += evt->data_len;
}
}
break;
case HTTP_EVENT_ON_FINISH:
ESP_LOGI(g_p_tag, "HTTP_EVENT_ON_FINISH");
g_http_response_buffer[output_len] = '\0'; // <- HERE!
ESP_LOGI(g_p_tag, "Dato finale: %s", (char *) evt->user_data);
output_len = 0;
break;
}
return ret;
} /* client_event_handler() */
How can I insert the terminator string by using a pointer to user_data?
I tried (evt + output_len)->user_data = '\0' but it seems wrong.
How can I insert the terminator string by using a pointer to user_data?
You cannot "insert" into arrays strictly speaking. You can assign a char in any index to be a null terminator like this:
char* ptr_to_user_data = config.user_data;
assert(index < MAX_HTTP_OUTPUT_BUFFER);
ptr_to_user_data[index] = '\0';
Related
I am trying to insert Node to Binary tree. This is my function for creating Node (rest is done).
void BVSCreate_function(TNodef *rootPtr, function_save token) {
TNodef *newPtr = malloc(sizeof(struct tnodef));
if (newPtr == NULL) {
fprintf(stderr, "99");
return;
}
TNodef init;
string initStr;
initStr.str = NULL;
initStr.length = 0;
initStr.alloc = 0;
newPtr = &init;
newPtr->content = &initStr;
newPtr->leftPtr = NULL;
newPtr->rightPtr = NULL;
newPtr->return_type = token.ret_value;
newPtr->parameters = token.param_count;
strCpyStr(newPtr->content, token.content);
rootPtr = newPtr;
}
void BVSInsert_function(TNodef *rootPtr, function_save token) {
if (rootPtr == NULL) {
BVSCreate_function(rootPtr, token);
} else {
if ((strCmpStr(token.content, rootPtr->content)) < 0) {
BVSCreate_function(rootPtr->leftPtr, token);
} else
if ((strCmpStr(token.content, rootPtr->content)) > 0) {
BVSCreate_function(rootPtr->rightPtr, token);
}
}
}
When TNodef and function_save are structs:
typedef struct {
string *content;
int param_count;
int ret_value;
} function_save;
typedef struct tnodef {
string *content;
struct tnodef *leftPtr;
struct tnodef *rightPtr;
int parameters;
int return_type;
} TNodef;
Where string is defined as this struct:
typedef struct {
char *str; // content of string
int length; // length of string
int alloc; // amount of memory allocated
} string;
strCpystr function :
int strCpyStr(string *s1, string *s2) {
int len2 = s2->length;
if (len2 > s1->alloc) {
if (((s1->str) = (char *)realloc(s1->str, len2 + 1)) == NULL) {
return 1;
}
s1->alloc = len2 + 1;
}
strcpy(s1->str, s2->str);
s1->length = len2 + 1;
return 0;
}
I am trying to create a node in binary tree and put there information from struct function_save.
But when I try to print this tree after insert it shows me that tree is still empty.
Your code in BVSCreate_function has undefined behavior because:
newPtr = &init; discards the allocated node and instead uses a local structure that will become invalid as soon as the function returns.
newPtr->content = &initStr; is incorrect for the same reason: you should allocate memory for the string too or possibly modify the TNodeDef to make content a string object instead of a pointer.
Function BVSInsert_function does not return the updated root pointer, hence the caller's root node is never updated. You could change the API, passing the address of the pointer to be updated.
There is also a confusion in BVSInsert_function: it should call itself recursively when walking down the tree instead of calling BVSCreate_function.
Here is a modified version:
/* Allocate the node and return 1 if successful, -1 on failure */
int BVSCreate_function(TNodef **rootPtr, function_save token) {
TNodef *newPtr = malloc(sizeof(*newPtr));
string *newStr = malloc(sizeof(*content));
if (newPtr == NULL || newStr == NULL) {
fprintf(stderr, "99");
free(newPtr);
free(newStr);
return -1;
}
newStr->str = NULL;
newStr->length = 0;
newStr->alloc = 0;
newPtr->content = newStr;
newPtr->leftPtr = NULL;
newPtr->rightPtr = NULL;
newPtr->return_type = token.ret_value;
newPtr->parameters = token.param_count;
strCpyStr(newPtr->content, token.content);
*rootPtr = newPtr;
return 1;
}
int BVSInsert_function(TNodef **rootPtr, function_save token) {
if (*rootPtr == NULL) {
return BVSCreate_function(rootPtr, token);
} else {
if (strCmpStr(token.content, rootPtr->content) < 0) {
return BVSInsert_function(&rootPtr->leftPtr, token);
} else
if ((strCmpStr(token.content, rootPtr->content)) > 0) {
return BVSInsert_function(&rootPtr->rightPtr, token);
} else {
/* function is already present: return 0 */
return 0;
}
}
}
Note also that function strCpyStr may write beyond the end of the allocated area is len2 == s1->alloc, assuming s1->len is the length of the string, excluding the null terminator.
Here is a modified version:
int strCpyStr(string *s1, const string *s2) {
int len2 = s2->length;
if (len2 >= s1->alloc) {
char *newstr = (char *)realloc(s1->str, len2 + 1);
if (newstr == NULL) {
return 1;
}
s1->str = newstr;
s1->alloc = len2 + 1;
}
strcpy(s1->str, s2->str);
s1->length = len2;
return 0;
}
I'm implementing a hash table in c and I chose as key the sha256 hash of the file that I need to store. The problem is that I need to convert the key to a reusable index to insert in the hash table. I tought to rehash the key, but this way I would increase the possibility of overlapping values. Is there a way to use this hash as the key to the table?
The sha256 is store as a BYTE[32] or can be converted as a sting
void* ht_get(ht* table, const char *key) {
size_t index = magicfunction(key);
while (table->entries[index].key != NULL) {
if (strcmp(key, table->entries[index].key) == 0) {
// Found key, return value.
return table->entries[index].value;
}
// Key wasn't in this slot, move to next (linear probing).
index++;
if (index >= table->capacity) {
index = 0;
}
}
return NULL;
}
When I need an absolute minimalist hashmap in C, I usually end up doing something like that:
#include <stddef.h>
#include <string.h>
#include <stdio.h>
struct hmap_entry {
const char *key;
/* Or in your case: */
/* char key[SIZE_OF_SHA256]; */
void *payload;
};
#define HMAP_ENTRY_CNT 256
struct hmap {
struct hmap_entry entries[HMAP_ENTRY_CNT];
};
static size_t str_hash(const char *s) {
size_t hash = 0;
while(*s) {
hash = (hash << 7) ^ (size_t)*s++ ^ hash;
}
return hash;
}
static struct hmap_entry *hmap_search_entry(struct hmap *map
, const char *key)
{
size_t hash = str_hash(key);
/* Or in your case: */
/* size_t hash = 0; memcpy(&hash, key, sizeof(key)) */
hash = hash % HMAP_ENTRY_CNT;
struct hmap_entry *e = NULL;
while(1) {
e = map->entries + hash;
if(e->key == NULL
|| strcmp(key, e->key) == 0) {
break;
}
/* Or in your case: */
/* if(e->key == NULL
|| memcmp(key, e->key, SIZE_OF_SHA256) == 0) {
break;
}
*/
hash = (hash + 1) % HMAP_ENTRY_CNT;
}
return e;
}
And this is how I use it:
int main()
{
struct hmap_entry *e;
struct hmap map = {};
/* insert foo */
e = hmap_search_entry(&map, "foo");
e->key = "foo";
e->payload = "hello world";
/* insert bar */
e = hmap_search_entry(&map, "bar");
e->key = "bar";
e->payload = "Something else";
/* get foo */
e = hmap_search_entry(&map, "foo");
if(e->key) {
printf("Value of \"%s\" is \"%s\"\n", e->key, (const char *)e->payload);
}
else {
printf("Not found!\n");
}
/* get bar */
e = hmap_search_entry(&map, "bar");
if(e->key) {
printf("Value of \"%s\" is \"%s\"\n", e->key, (const char *)e->payload);
}
else {
printf("Not found!\n");
}
/* get test */
e = hmap_search_entry(&map, "test");
if(e->key) {
printf("Value of \"%s\" is \"%s\"\n", e->key, (const char *)e->payload);
}
else {
printf("Not found!\n");
}
return 0;
}
This question already has an answer here:
Dynamic memory access only works inside function
(1 answer)
Closed 5 years ago.
this is my code:
void n(FILE *f, int *pocet, char **spz) {
int i = 0;
int pocett = 0;
char* r = (char*)malloc(50 * sizeof(char));
if (spz != NULL) {
free(spz);
}
spz = (char**)malloc(sizeof(char*));
if (f == NULL) {
printf_s("File is null");
return;
}
while (fgets(r, 50, f)) {
switch (i % 6) {
case 1: {
if (i == 1) {
spz[0] = (char*)malloc(50 * sizeof(char));
spz[0] = r;
}
else {
spz = (char**) realloc(spz,((i - 1) / 6 + 1) * sizeof(char*));
spz[((i - 1) / 6)] = (char*)malloc(50 * sizeof(char));
strcpy_s(spz[(i-1)/6], 50 ,r);
}
break;
}
case 5: {
pocett++;
break;
}
}
i++;
}
*pocet = ++pocett;
}
and I call my function as this:
int main() {
FILE *f = NULL;
int c;
int pocet = 0;
int* p = &pocet;
char** spz = NULL;
while ((c = getchar()) != 'k') {
getchar();
switch (c) {
case 'v': {
v(&f);
break;
}
case 'o': {
//printf_s("AHOJ\n");
break;
}
case 'n': {
n(f, p, spz);
break;
}
case 's': {
s(spz, *p);
break;
}
case 'p': {
printf_s("AHOJ\n");
break;
}
case 'z': {
printf_s("AHOJ\n");
break;
}
default: {
printf_s("Skus znova\n");
break;
}
}
}
return 0;
}
EDIT: I have edited my code to add main method.
the problem is, when I pass the spz to another method after, it is null, that means I have to use it in method n() as triple pointer, but it is not working when I add asterisk before each spz in method n. Do you have any ideas how to fix this ?
When you call a function you pass a copy of the spz variable from the main() function to an spz variable in the n() function. Then, assignment in n() affects only its local spz.
If you want to get a pointer value back, you need to pass a pointer to the variable and the routine must dereference the pointer to reach the original variable:
void n( char ***spz_ptr) // a pointer to (char **) variable
{
*spz_ptr // dereferenced pointer. i.e. the main's spz
= malloc( ... );
}
void main()
{
char **spz;
n( & spz ); // pass a pointer to spz
if( spz == NULL) { // test the value assigned by n()
.... // handle the error
}
else {
.... // proceed with actual work
}
}
I posted a few questions about my project already and its all been helpful but I'm still unsure of one part of it.
I'm creating a translator that converts ASCII to ASH and ASH to ASCII. I have now successfully converted ASCII to ASH but can't convert from ASH to ASCII. I've created a function called 'ASCIIstring2ASHstring' which works fine, but I now have to create another function called 'ASHstring2ASCIIstring'. However, I've been told that for this function I need to save each character the user enters into a temporary buffer until a '/' appears, at which point I need to print out all the characters in the temporary buffer as a full string by calling the 'ASHstring2ASCIIstring' function (which I'm asking for help creating now) . However, I have no idea how I'd do this and I hoped someone here could lend me a hand :)
Thanks!
UPDATE: I have now created the function with some help, but for some reason its not printing out ASH to ASCII translations as expected, I have posted the updated code below.
char ASH_a[] = "*";
char ASH_b[] = "!!*";
char ASH_c[] = "!!#";
char ASH_d[] = "*!";
char ASH_e[] = "!";
char ASH_f[] = "!*!";
char ASH_g[] = "**";
char ASH_h[] = "!**";
char ASH_i[] = "!!";
char ASH_j[] = "*!!";
char ASH_k[] = "*#";
char ASH_l[] = "!*#";
char ASH_m[] = "!*";
char ASH_n[] = "!#";
char ASH_o[] = "#*";
char ASH_p[] = "!#!";
char ASH_q[] = "*!#";
char ASH_r[] = "!#*";
char ASH_s[] = "#!";
char ASH_t[] = "#";
char ASH_u[] = "##";
char ASH_v[] = "**!";
char ASH_w[] = "***";
char ASH_x[] = "*#!";
char ASH_y[] = "!##";
char ASH_z[] = "**#";
//char ASH_1[] = "#!!*";
//char ASH_2[] = "#!!#";
//char ASH_3[] = "#!*!";
//char ASH_4[] = "#!**";
//char ASH_5[] = "#!*#";
//char ASH_6[] = "#!#!";
//char ASH_7[] = "#!#*";
//char ASH_8[] = "#!##";
//char ASH_9[] = "#*!!";
//char ASH_0[] = "#!!!";
//char ASH_.[] = "#!!";
//char ASH_,[] = "#!*";
//char ASH_?[] = "#**";
//char ASH_![] = "#*#";
//char ASH_+[] = "##!";
//char ASH_-[] = "##*";
//char ASH_*[] = "###";
//char ASH_/[] = "#!#";
char t[] = "ash code";
char buffer1[100];
const int oblen = 100;
char ob [oblen];
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
// Serial.println(ASH2ASCII("!**")); //These are the ASH characters I want to convert to ASCII using the ASH2ASCII function
//Serial.println(ASH2ASCII("!"));
//Serial.println(ASH2ASCII("!*#"));
//Serial.println(ASH2ASCII("!*#"));
//Serial.println(ASH2ASCII("#*"));
//ASCIIstring2ASHstring (t, ob, oblen);
//Serial.println(ob);
usinput(buffer1);
Serial.print(buffer1);
chardecide(buffer1);
}
void chardecide(char * buffer1) { //char decide which acts upon the result of isASH using the true and false returns
if (isASH (buffer1)) {
Serial.println(" has been recognized as ASH - ");
ASHstring2ASCIIstring(buffer1, ob); //passes function with buffer1 and ob included
Serial.println(ob);
} else {
Serial.println(" has been recognized as ASCII - ");
ASCIIstring2ASHstring (buffer1, ob, oblen);
Serial.println(ob);
}
}
void usinput(char * ib ) {
char inChar;
int i = 0;
do {
while (!Serial.available()) {};
inChar = Serial.read();
if (inChar == '\n') {
break;
} else {
ib[i] = inChar;
i++;
}
ib[i] = '\0';
} while (true);
}
bool isASH(char * buffer1)
{
if (buffer1[0] != '*' && buffer1[0] != '!' && buffer1[0] != '#') return false;
return true;
}
int ASHstring2ASCIIstring(char *buffer, char *ob) //converts ash to ascii
{
char str[10];
int j = 0;
int l = 0;
while (*buffer) {
if (*buffer == '/') { //hit slash
str[j] = '\0'; //empty buffer
ob[l++] = ASH2ASCII(str);
j = 0;
} else {
if (j + 1 < sizeof(str)) {
str[j++] = *buffer;
}
}
buffer++;
}
ob[l] = '\0';
return l;
}
void ASCIIstring2ASHstring (char * ip, char * op, int oplen) { //converts ascii to ash
op[0] = '\0';
int bp = 0;
int n;
char m[9];
int l = strlen(ip);
for (int i = 0; i < l; i++) {
m[0] = '\0';
strcpy(m, ASCII2ASH(ip[i]));
n = strlen(m);
if ((bp + n + l) < oplen) {
strcat(op , m);
bp = bp + n;
}
if (ip[i] != ' ' && ip[i + l] != ' ') {
op[bp] = '/';
bp++;
}
op[bp] = '\0';
}
}
char ASH2ASCII(char * m) { //Using the char variables impmented globally, ASH2ASCII searches through specific variables until it finds a match for the conversion, at which point it will capture and reuturn the ASCII string
if (strcmp(ASH_a, m) == 0) { //if string captured return a
return 'a';
}
else if (strcmp(ASH_b, m) == 0) { //else if b string is captured return
return 'b';
}
else if (strcmp(ASH_c, m) == 0) {
return 'c';
}
else if (strcmp(ASH_d, m) == 0) {
return 'd';
}
else if (strcmp(ASH_e, m) == 0) {
return 'e';
}
else if (strcmp(ASH_f, m) == 0) {
return 'f';
}
else if (strcmp(ASH_g, m) == 0) {
return 'g';
}
else if (strcmp(ASH_h, m) == 0) {
return 'h';
}
else if (strcmp(ASH_i, m) == 0) {
return 'i';
}
else if (strcmp(ASH_j, m) == 0) {
return 'j';
}
else if (strcmp(ASH_k, m) == 0) {
return 'k';
}
else if (strcmp(ASH_l, m) == 0) {
return 'l';
}
else if (strcmp(ASH_m, m) == 0) {
return 'm';
}
else if (strcmp(ASH_n, m) == 0) {
return 'n';
}
else if (strcmp(ASH_o, m) == 0) {
return 'o';
}
else if (strcmp(ASH_p, m) == 0) {
return 'p';
}
else if (strcmp(ASH_q, m) == 0) {
return 'q';
}
else if (strcmp(ASH_r, m) == 0) {
return 'r';
}
else if (strcmp(ASH_s, m) == 0) {
return 's';
}
else if (strcmp(ASH_t, m) == 0) {
return 't';
}
else if (strcmp(ASH_u, m) == 0) {
return 'u';
}
else if (strcmp(ASH_v, m) == 0) {
return 'v';
}
else if (strcmp(ASH_w, m) == 0) {
return 'w';
}
else if (strcmp(ASH_x, m) == 0) {
return 'x';
}
else if (strcmp(ASH_y, m) == 0) {
return 'y';
}
else if (strcmp(ASH_z, m) == 0) {
return 'z';
}
}
void ASCIIstring2ASH (char * buf) {
Serial.println(ASCII2ASH(*t));
}
char * ASCII2ASH (char c) { //This is the opposire of ASH2ASCII, it uses the globally defined variables to search through ASCII characters, and returns the ASH version of that character
switch (c) {
case 'a':
return ASH_a;//returns ASH version of a if matched
case 'b':
return ASH_b;
case 'c':
return ASH_c;
case 'd':
return ASH_d;
case 'e':
return ASH_e;
case 'f':
return ASH_f;
case 'g':
return ASH_g;
case 'h':
return ASH_h;
case 'i':
return ASH_i;
case 'j':
return ASH_j;
case 'k':
return ASH_k;
case 'l':
return ASH_l;
case 'm':
return ASH_m;
case 'n':
return ASH_n;
case 'o':
return ASH_o;
case 'p':
return ASH_p;
case 'q':
return ASH_q;
case 'r':
return ASH_r;
case 's':
return ASH_s;
case 't':
return ASH_t;
case 'u':
return ASH_u;
case 'v':
return ASH_v;
case 'w':
return ASH_w;
case 'x':
return ASH_x;
case 'y':
return ASH_y;
case 'z':
return ASH_z;
case ' ':
return " ";
default:
Serial.println("switching went wrong!");
break;
}
}
void loop() {
}
In <string.h>, there is a function strtok that splits a string on a range of given characters. You could use it like this:
int ASHstring2ASCIIstring(char *buffer, char *ob)
{
char *token;
int l = 0;
token = strtok(buffer, "/");
while (token) {
println(token);
ob[l++] = ASH2ASCII(token); // Note: No overflow check!
token = strtok(NULL, "/");
}
ob[l] = '\0';
return l;
}
On the first call, you supply the string to split, on subsequent calls you pass NULL to tell strtok to keep working on the same string. This code destroys the original string in the process, because it places end markers at the end of the tokens.
You can also code that behaviour yourself by filling an auxiliary buffer. When you hit a slash, process the buffer and empty it:
int ASHstring2ASCIIstring(char *buffer, char *ob)
{
char str[10];
int j = 0;
int l = 0;
while (*buffer) {
if (*buffer == '/') {
str[j] = '\0';
ob[l++] = ASH2ASCII(str);
j = 0;
} else {
if (j + 1 < sizeof(str)) {
str[j++] = *buffer;
}
}
buffer++;
}
ob[l] = '\0';
return l;
}
This code leaves the string intact. It also requires that there is a slash after the last token. That may not be what you want, but it might be a good starting point.
I am tried to implement next() PHP function in C. if I have
The different to my implementation is I want to do this work with more one points. For example:
if I have two char * like:
char * a = "ac\0";
char * b = "bd\0";
and I call:
printf("%c", cgetnext(a));
printf("%c", cgetnext(b));
printf("%c", cgetnext(a));
printf("%c", cgetnext(b));
gets an output like: abcd
but I get abab
here is my code:
`#include <string.h>
#include <stdlib.h>
typedef struct
{
int pLocation;
int myindex;
int lastIndex;
} POINTERINFORMATION;
int __myIndex = 0;
int pointersLocationsLength = 0;
char * temparr = NULL;
POINTERINFORMATION pointersLocations[256];
int
plAdd (int p)
{
if (pointersLocationsLength >= sizeof(pointersLocations)) {
return -1;
} else {
pointersLocations[pointersLocationsLength].pLocation = p;
pointersLocations[pointersLocationsLength].lastIndex = 0;
pointersLocationsLength ++;
return pointersLocationsLength;
}
}
int
getPointer (int p, POINTERINFORMATION * out)
{
int i;
for (i = 0; i < pointersLocationsLength; i++)
{
if(pointersLocations[pointersLocationsLength].pLocation == p)
{
pointersLocations[i].myindex = i;
*out = pointersLocations[i];
return 1;
}
}
return 0;
}
void
getPointerIndex(char ** variable, int * val)
{
char * buf = malloc(256);
if(sprintf(buf,"%p", &variable) > 0){
*val = strtol(buf, NULL, 16 );
} else {
*val = -1;
}
}
int
inArrayOfPointers (int pointer)
{
POINTERINFORMATION pi;
return getPointer(pointer, &pi);
}
char
cgetnext(char * arr)
{
char * myarr;
const size_t size = sizeof(char *) + 1;
int pof;
myarr = malloc(size);
getPointerIndex (&arr, &pof);
if (inArrayOfPointers(pof)){
POINTERINFORMATION pi;
if (getPointer(pof, &pi))
{
myarr = (char *)*(int *)pi.pLocation;
__myIndex = pi.lastIndex;
++pointersLocations[pi.myindex].myindex;
} else {
return 0;
}
} else {
if (plAdd(pof) == -1) {
printf(" CANNOT ADD ELEMENT TO ARRAY\n");
exit(0);
} else {
myarr = arr;
__myIndex = 0;
}
}
if (strlen(myarr) == __myIndex) {
return 0;
} else {
temparr = malloc(size);
temparr = strdup(myarr);
return myarr[__myIndex];
}
}`
how to fix this? differents solutions for solve it are very apreciated! Thanks in advance.
If you are specifically interested in char* "arrays", then a simple solution might be to just increment the pointer. Note that if using dynamically allocated memory, you need to save the original pointer to free it. The same idea could be used for other data types as well.
This is an example of what I mean. cgetnext here just returns the character at the current position in the array and increments pointer (that is passed by address).
char cgetnext( char **p )
{
assert( p != NULL );
// check for end of string
if ( **p == '\0' )
return '\0';
return *(*p)++;
}
int main( int argc, char* argv[] )
{
char *a = "ac";
char *b = "bd";
printf( "%c", cgetnext(&a));
printf( "%c", cgetnext(&b));
printf( "%c", cgetnext(&a));
printf( "%c", cgetnext(&b));
}