1

I am currently trying to handle string in C and I am having trouble placing the split values of a string into an array. Bellow is the code I have created in an attempt to achieve this.

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

 int main(){
     char str[]="titanic.txt";
     char parts[2][5];
     char *name = strtok(str, ".");
     for (int i = 0; i < 2; i++){
          parts[i][5] = name;
          char name = strtok(NULL, ".");

     }
     printf("%c\n", str[0]);
     return 0;
  }

The output I would be expecting from this would hopefully look something like this.

 char part[2][10]{
     {'t', 'i', 't', 'a', 'n', 'i', 'c'},
     {'t', 'x', 't'}
 };

alternatively, I have tried something like this using string copy as such.

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

 int main(){
     char str[]="titanic.txt";
     char parts[2][10];
     char *name = strtok(str, ".");
     for (int i = 0; i < 2; i++){
         strcpy(parts[i], name);
         name = strtok(NULL, ".");

      }
     printf("%s\n", parts[1]);
     return 0;
 }

Which, did what I want it to, but I would like to try and achieve this without string copy because I feel it will help me understand strings, characters, and arrays better. I do not want to reinvent the wheel I just want a deeper understanding.

Dylan Edmonds
  • 47
  • 1
  • 6
  • 1
    If you want to *copy* strings, you will have to use `strcpy`. This is the C way to copy strings. Of course you can have an array of *pointers* which are simply pointing to different parts of your original string. – Eugene Sh. Feb 19 '19 at 21:07
  • 4
    Enable all your compiler warnings, and address the problems they reveal. – Andrew Henle Feb 19 '19 at 21:07
  • in the second code example, the only output will be: 'txt' I.E. neither code example will output what your question states as the desired output – user3629249 Feb 21 '19 at 06:49
  • in the first code example, the ONLY output from the code will be the `t` not that whole array of outputs. – user3629249 Feb 21 '19 at 06:50

3 Answers3

2

The parts array should be an array of pointers, not a 2-dimensional array of characters:

char *parts[2];

Then you assign:

parts[i] = name;

If you want to copy from the input string to parts, you need to declare the 2nd dimension large enough for the largest possible string:

char parts[2][10];

and then you should use strcpy() rather than assignment to copy it.

strcpy(parts[i], name);

Notice that you don't give a second index to parts when doing this, that's only used to access specific characters of the string, not the string as a whole.

Barmar
  • 741,623
  • 53
  • 500
  • 612
1

In case separating a file name from its extension is actually relevant to whatever you're trying to accomplish, I'll assume you're using Windows and point you to the documentation for the recommended Windows API library for this, <pathcch.h>.

With regard to your actual question, your first code doesn't work because:

  1. You're assigning to a single character in the line parts[i][5] = name;. You're also overflowing since parts[i] has the type char [5], which only has positions 0 to 4.
  2. You redeclare name as a single char rather than a char * pointer, which is the correct type, and was declared as such (correctly) outside the loop scope. Your new variable char name overwrites the existing char *name variable.

You cannot get around using strcpy-family functions to assign to a character array for this (and most other) use cases. The only time the syntax char foo[] = "Hello World"; is valid is immediately on declaration. Also, string literals are stored in read-only memory.

Govind Parmar
  • 20,656
  • 7
  • 53
  • 85
0

Following your coding style, this is the solution:

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

int main()
{
    char str[] = "titanic.txt";
    char delim[] = ".";
    char parts[2][10];
    char *ptr = strtok(str, delim);
    int i = 0;

    for (i = 0; i < 2; i++){
        if(ptr != NULL)
        {                
            snprintf(parts[i], sizeof(parts[0])  ,"%s", ptr);
            ptr = strtok(NULL, delim);
        }
    }

    printf("'%s'\n", parts[0]);
    printf("'%s'\n", parts[1]);

    return 0;
}