Link to home
Start Free TrialLog in
Avatar of akohan
akohan

asked on

How to work with array of string?

Hello group,

In a function I have:

void func (void *s, size_t i, void *p)
{
   printf("in cb1: %s\n", s); //this printst a complete string
}

however, I want to store all of them in an array so I need to have an array of strings. How can I do this? any help is appreciated.

Thanks.


Avatar of Shahzad Fateh Ali
Shahzad Fateh Ali
Flag of Pakistan image

Hi,

You can tokenize the string. Here is its tutorial.

http://www.elook.org/programming/c/strtok.html
>> however, I want to store all of them in an array

All of them what ? What are you referring to ?

Why are the function arguments void*'s ?
Avatar of akohan
akohan

ASKER



Hello,

I'm using libcsv library to handle CSV file and it has few examples. I need to extract data from CSV file so I found a function in it as

void func (void *s, size_t i, void *p) { some code}

I check that *s points to each data being parsed using the library.  like: "aaa", "bbb", "ccc"
so in each iteration it points to aaa then bbb and ...

I thought it would be a good way to store them in a dynamic array (array of strings).

Any suggestions is appreciated.

Regards.


Are you talking about modifying the source of the library ? Isn't there an external library API that does what you need ?
Or is this a callback function ? If so, yes, you can place them in an array if that's what you wish.
Avatar of akohan

ASKER


Hello,

Thanks for your response. This is a code from example directory and yes it is a callback function (although I'm not sure what is the exact definition of it - but it is called callback function in its documentation).

Now, when I assign it to a the array it complains of assigning  from void* to char* so I did a type cast but still get that message!

Any comments?


>> (although I'm not sure what is the exact definition of it - but it is called callback function in its documentation).

A callback function is a function that you pass to the library, and whenever the library has data for you, it will call this function with the data as parameter (in this context). Basically, the library "calls back" to your code, hence the name.


>> Now, when I assign it to a the array it complains of assigning  from void* to char* so I did a type cast but still get that message!

Can you show your code ? As well as the exact error message you get ?
Avatar of akohan

ASKER



Thanks for the explanation!

I don't have access to the machine which has the code currently but this is the body of the function I need to change:


void cb1 (void *s, size_t i, void *p) {

   /* this is the part I have to get the data and store it into an array

   assuming data is a char* so I need to assign what s points to into it
   
    data[count++] = s;  //however, s is  void* and data is char* any idea what I should do?


    ends here
   */



  if (put_comma)
    putc(',', stdout);
  csv_fwrite(stdout, s, i);
  put_comma = 1;

}
>> //however, s is  void* and data is char* any idea what I should do?

If you're working in C, that shouldn't matter. A C++ compiler will complain about it though.


Btw, you probably should make a copy of the string before storing it in the array, since I assume that the library will not keep it in memory after calling the callback function.
Avatar of akohan

ASKER


Hello Inifinity,

you said :

>> you probably should make a copy of the string before storing it in the array

Why do I need to copy it when I have stored it into an array?

Regards,
>> Why do I need to copy it when I have stored it into an array?

Because the string will probably no longer be available after the function returns (the library will likely free the memory). If you want to keep the string for later use, you should make a copy of the string.
Avatar of akohan

ASKER


Hi again,

Currently, I'm having is that I get the following errors. Can you address me what to do?


csvtest.c:37: error: conflicting types for 'input'
csvtest.c:32: error: previous declaration of 'input' was here
csvtest.c:38: warning: initialization makes integer from pointer without a cast
csvtest.c:38: error: initializer element is not constant
csvtest.c:38: error: syntax error before "size"
csvtest.c: In function `cb1':
csvtest.c:42: error: subscripted value is neither array nor pointer
csvtest.c:42: warning: dereferencing `void *' pointer
csvtest.c:43: error: subscripted value is neither array nor pointer


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "libcsv/csv.h"
 
static int put_comma;
 
char* input;     //line 32
int size = 0;
int count = 0;
 
 
input = (char*)malloc(1024) //line 37
size = strlen(input) + 1; //line 38
 
void cb1 (void *s, size_t i, void *p) {
 
   input[count] = *s;   //line 42
   printf("\n(%s)", input[count]); //line 43
   count++;
 
 
  if (put_comma)
    putc(',', stdout);
  csv_fwrite(stdout, s, i);
  put_comma = 1;
}

Open in new window

Avatar of akohan

ASKER


I guess the issues are solved! but it would be great if you could advise me since it works for now but I'm not sure if it has been a proper approach:

I changed :

    char* input      =>      char** input

and for now (just to make it work) put everything locally in cb1 ().

Any suggestions?

Regards.

Can you show your new code ?
Avatar of akohan

ASKER



Sorry for the delay I didn't have access to my machine. I will send it tonight.

Regards,
Avatar of akohan

ASKER



Hi again,

Ok regarding my question (above) I need to explain some details first:

0) I'm using a library aka libcsv.
1) using a callback (as Infinity explained it) function I'm getting data from a csv file.
2) the prototype of the function is:

              void cb1 (void *s, size_t i, void *p)

so *s always is pointing to a piece of data. Let's say in the csv file we have:
            1           2            3                     4
       "data1", "data2","data3", "data7 data8 data9 ...."

hence,  *s value will be "data1" then "data2"

3) a stuct is defined as:

       struct mystruct {
          char*  fld1;  
          char*  fld2;
          char*  fld4;
      };

Now question:

using a callback function I can get number of rows so I have to create an array of struct. Now, I guess I can do something like:

 rows = get_rows();
 accounts = mcalloc( rows, sizeof(struct mystruct));

1) Is this right?

2) when I assign each data item to struct fields, how should I take care of sizing of data? or this would be automatically handled by the compiler?
3) How can I close each field's data with '\0' ? to avoid pointer issues?

Regards.

ASKER CERTIFIED SOLUTION
Avatar of Infinity08
Infinity08
Flag of Belgium image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of akohan

ASKER



Thanks again!

Isn't better to stick to link-list rather than using array? the thing is that I have to count number of rows in the csv file first and then read them again to feed the array. However, using link-list I can read the data without worrying on number of lines in the csv file!

Regards.
I never said you had to use an array ;) Different kinds of data structures might work better depending on your specific requirements. If you don't know the amount of records, then a dynamicaly growing data structure (like a linked list) might indeed be a better option.
Avatar of akohan

ASKER


no, I didn't mean you said :)
That was the first things which crossed my mind but then as you say link-list will be more optimized way of doing it, so I guess you will see my next questions on link list here :)

Thanks for your help.

Regards.