tags:

views:

91

answers:

5
+2  Q: 

string array in c

How do you use a string array as a parameter in C? If I were to write a function with signature:

Guess i didnt explain myself very well... I'll post the code that i'm trying to get to work.

int format_parameters(char* str) {

    char local_str[201] = "";
    int i = 0;
    int j = 0;
    int flip = 0;

    while(str[i]) {

        if((str[i] == '"') && (flip == 0)) flip = 1;//Sentence allowed
        else if((str[i] == '"') && (flip == 1)) flip = 0;//Sentence not allowed

        if(flip == 1) append_char(local_str, str[i]);
        //check if space
        else if(flip == 0) {

            int c = str[i];
            if(!isspace(c)) append_char(local_str, str[i]);

            else {
                if((strlen(local_str) > 0) && (j < 4)) {
                    //local-str copied to param[j] here
                    //printf("j = %d %s\n",j,local_str);

                    local_str[0] = '\0';
                    j++;
                }
            }
        }
        i++;
    }

    //Add \0 to param

    return flip;
}//end format_parameters


void append_char(char* str, char c) {
    int len = strlen(str);
    str[len] = c;
    str[len+1] = '\0';
}//end append_char

int main() {
        char str[200];
        //str filled with stuff...
        int x = format_parameters(str);
}

There should be a second (and third?) parameter in format_parameterssignature, a char* param[5] which should be readable from main.

+1  A: 

Does this work?

#include <string.h>
#include <assert.h>
#include <stdio.h>

int format_parameters(char *str, char *param[], size_t nparam)
{
    char **next = param;
    char **end  = param + nparam;
    char  *data = str;

    assert(str != 0 && param != 0 && nparam != 0);

    while (next < end && *data != '\0')
    {
        *next++ = data;
        data = strchr(data, ' ');   // Choose your own splitting criterion
        if (data == 0)
            break;
        *data++ = '\0';
    }
    return(next - param);
 }

 int main(void)
 {
     char  str[] = "a b c d";
     char *param[5];
     int   nvals = format_parameters(str, param, 5);
     int   i;

     for (i = 0; i < nvals; i++)
         printf("Param %d: <<%s>>\n", i+1, param[i]);

     return 0;
  }

The return value is the number of parameters found. If you pass an empty string, that would be 0. Beware leading, trailing and repeated blanks; the code works - but maybe not as you want it to.

Jonathan Leffler
@schot: if the input string was not modifiable, it would have a `const char *` type.
Jonathan Leffler
+1 This approach works great.
schot
I think ypu're doing his homework.
Matt H
A: 

This is entirely about memory allocation.

If you allocate static memory for param before the function is called, the memory will exist in that scope.

Otherwise take a look at dynamic allocation, it will exist until you tell it to go away.

Luca Matteis
A: 

Let me take a stab at this. Arrays are "second-class citizens" in C. There is no such type as "function returning array of ...". Since you are already passing param as a char *.

You must be having a reference of it in the calling function. So when you modify *param (note that if you modify just param it's local & will not persist outside this function) your calling function can also see this change.

Or you could use the keyword static and param persists even after you exit the function. But note that static might cause problems if you are planning to convert your program to use threads later on.

MovieYoda
-1: Using static is no recommended way in this case.
ur
@ur Hey! it's not recommended. That's what even I mentioned. But it's a way to do. I am just mentioning that. No need to down vote for that !!
MovieYoda
A: 

As Jonatahan pointed out, you need more parameters:

int format_parameters(char* strInput, char* paramOutput[], size_t cbMaxParams );
// return value is actual number of parameter strings in paramOutput

paramOutput is an array of pointers. So the caller has to provide an array of pointers and the called function has to allocate memory for the strings and set the pointers in the array:

// main:
#define SIZE 20
char * params[SIZE];

int result = format_parameters( szInput, params, SIZE );
// after use go through params and free all pointers 

// function:
int format_parameters(char* strInput, char* paramOutput[], size_t cbMaxParams )
{
  // ...

  for( size_t i=0; (i<cbMaxParams) && (!noMoreParams); i++ )
  {
     // ... 
     paramOutput[i] = (char *)malloc( xxxx );
     // ...
  }

  // ...
}  
ur
A: 

You have to create the char* param[] array outside the function and just pass it as a parameter:

int paramCount = countParameters(str);  // you have to create this function
char* param[] = malloc(paramCount * sizeof(char*));
format_parameters(str, param);

and inside the function:

int format_parameters(char* str, char* param[])
{
    int currentParamIndex = 0;

    ..........
        //TODO: check if currentParamIndex < paramCount
        char* currentParam  = str + currentParamStart; // currentParamStart is the start index of the parameter in the str containing all parameters
        param[currentParamIndex] = currentParam;
        currentParamIndex++;
    .............
}

And in order to write safe code you have to pass also the paramCount as a parameter to format_parameters so the function will not access an element out of the bounds of the array.

Or maybe you should just use getopt?

Andrei Bozantan