• C

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.


akohanAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Shahzad Fateh AliWeb Solutions Architect & Technical Project Manager- VentureDive (Pvt) LtdCommented:
Hi,

You can tokenize the string. Here is its tutorial.

http://www.elook.org/programming/c/strtok.html
0
Infinity08Commented:
>> 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 ?
0
akohanAuthor Commented:


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.


0
Problems using Powershell and Active Directory?

Managing Active Directory does not always have to be complicated.  If you are spending more time trying instead of doing, then it's time to look at something else. For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why

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

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?


0
Infinity08Commented:
>> (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 ?
0
akohanAuthor Commented:


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;

}
0
Infinity08Commented:
>> //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.
0
akohanAuthor Commented:

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,
0
Infinity08Commented:
>> 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.
0
akohanAuthor Commented:

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

0
akohanAuthor Commented:

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.

0
Infinity08Commented:
Can you show your new code ?
0
akohanAuthor Commented:


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

Regards,
0
akohanAuthor Commented:


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.

0
Infinity08Commented:
>> 1) Is this right?

Yes, you can allocate an array of structs using calloc :

        struct mystruct *accounts = (struct mystruct*) calloc(rows, sizeof(struct mystruct));


>> 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?

What do you mean by sizing of the data ? You simply create a copy of the string, and place it in the struct.


>> 3) How can I close each field's data with '\0' ? to avoid pointer issues?

By placing a '\0' at the end of each string.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
akohanAuthor Commented:


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.
0
Infinity08Commented:
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.
0
akohanAuthor Commented:

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.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.