0

I thought it would be pretty basic stuff. My C/C++ is rusty.. used it 14+ years back.. have been coding in perl, shell & python since and have a frustrating problem at hand in C code:

I have a string something like below in argv[7]:
Min:Max:Both:Both

I want to break it using colon and store it into array. then I want to access a certain element of array, pass it to a string var and pass it around a couple of functions.. my problem is in defining the string array and then passing around the string across functions, which is pretty basic stuff in scripting languages

I am doing something like this:

int main(int argc, char ** argv){
    int iy = 0;
    char * y = (char *)malloc(20*sizeof(char));
    char * tky = strtok(argv[7], ":");
      do {
        sprintf(y[iy],tky);
        printf("as string = %s and as array value = %s\n", tky, y[iy]);
        //printf("as string = %s \n", tky);
        iy++;
      } while((tky=strtok(NULL,":"))!=NULL);

      int measquant = 3;
      char colminmax[20];
        for(i=0; i<measquant; i++){
           sprintf(colminmax,"%s",y[i]);
           testfunction(colminmax);
         }
      return 0;
      }


      testfunction (char* dir){
              printf("dir is %s",dir);
         }

It is printing tky correctly and y[iy] as NULL Then I am trying to assign and pass it as:

Please help what am I missing. I have searched numerous C/C++ help sites but unable to get to something as basic.

dgarg
  • 318
  • 1
  • 3
  • 13
  • 8
    14 years ago was ... 2003? But you're still writing C instead of C++ ... Anyway, please post the [minimal _complete_ example](https://stackoverflow.com/help/mcve) that reproduces the problem, these code fragments aren't as useful as they might be – Useless Nov 30 '17 at 12:21
  • There are many better ways to split strings in c++ than using the infamous `strtok()`. – user0042 Nov 30 '17 at 12:22
  • Why is the question tagged with C++. I see only c-code! – Klaus Nov 30 '17 at 12:22
  • @user0042: Your comment might be helpful if you named one or two. – John Zwinck Nov 30 '17 at 12:23
  • 3
    The point was that strtok is infamous. It's almost always the worst. – sehe Nov 30 '17 at 12:23
  • For reference, even in 2003, you should have been using [`std::vector`](http://en.cppreference.com/w/cpp/container/vector)`<`[`std::string`](http://en.cppreference.com/w/cpp/string/basic_string)`>` instead of this. And probably `std::string::find()` (or variants thereof) and `std::string::substr()` instead of `strtok()`. – Useless Nov 30 '17 at 12:24
  • @sehe is right. But anyways [here](https://stackoverflow.com/questions/16286095/similar-function-to-javas-string-split-in-c) and [here](https://stackoverflow.com/questions/53849/how-do-i-tokenize-a-string-in-c) are some better ways, but it's easy to find tons of good examples at google. – user0042 Nov 30 '17 at 12:26
  • 1
    Possible duplicate of [How do I tokenize a string in C++?](https://stackoverflow.com/questions/53849/how-do-i-tokenize-a-string-in-c) – Mgetz Nov 30 '17 at 12:27
  • Guys my main issue is with the: char * y = (char *)malloc(20*sizeof(char)); and sprintf(yarr[iy],tky); Am I doing anything wrong here. And then sprintf(colminmax,"%s",y[i]); and testfunction (char* dir){ are correct> – dgarg Nov 30 '17 at 12:32
  • Apologies for tagging C++.. please have a look at C point of view. editing the tags – dgarg Nov 30 '17 at 12:34
  • What is this expected to do: `sprintf(yarr[iy],tky);`? What is `yarr` and where is your format string? You print wrong types: `printf("as string = %s and as array value = %s\n", tky, y[iy]);` Here `y[iy]` is a single `char` but you use `"%s"` format specifier. – Gerhardh Nov 30 '17 at 12:39
  • 1
    BTW: `main` is specified to return `int` type. – Gerhardh Nov 30 '17 at 12:48
  • Thanks Gerhardh . Edited the mistakes. yarr is changed to y. I know there are some mistakes in the code which is why it is giving seg fault. In sprintf(y[iy],tky), my intent is to store the sting in tky into one element of the array y. How do i correctly print it? and how to assign it correctly to colminmax – dgarg Nov 30 '17 at 12:51
  • 1
    `y` is a pointer to 20 `char`s. You can use it to store a single string up to 19 characters. But you seem to use it as an array or strings. You should rethink that part. – Gerhardh Nov 30 '17 at 13:36
  • everyone above except few like Gerhardh & John, i come back to SE after many years. I see less help and more hostility in these comments. An attitude of oneupmanship. You may be an expert in something & asker may be a novice. Help if you can or simply guide if you have time to write in a few words. Don't if you dont. but stay polite. humble? even better. – dgarg Dec 01 '17 at 09:47

1 Answers1

1

In char *y = (char*)malloc(20*sizeof(char)), the y acts as "array of characters". It can store a character up to 20 bytes long including the null-character. But your intention is to declare an "array of strings" instead.

You have to declare array of string instead (let's call it arr) and allocate memory for each element in the array. Then use strcpy to copy to that element. Or you can use strdup as shown in the example below.

You are accessing argv[7], but you didn't check if argc >= 7. Note that the command line argument is already available as an array.

int main(int argc, char ** argv) 
{
    printf("argc = %d\n", argc);
    for(int i = 0; i < argc; i++)
        printf("argv[%d] = %s\n", i, argv[i]);

    int count = 0;
    char **arr = malloc(20 * sizeof(char*));

    //commented out for testing
    //if(argc < 7) return 0;
    //char *token = strtok(argv[7], ":");

    //use source instead of argv[7] for testing
    char source[] = "Min:Max:Both:Both";

    char *token = strtok(source, ":");
    while(token)
    {
        arr[count++] = strdup(token);
        token = strtok(NULL, ":");
    }

    for(int i = 0; i < count; i++)
        printf("%s\n", arr[i]);

    return 0;
}
Barmak Shemirani
  • 30,904
  • 6
  • 40
  • 77