1

I've got a block of strings, say "aaa\0bbbb\0ccccccc\0" and I want to turn them into an array of strings. I've tried to do so using the following code:

void parsePath(char* pathString){
  char *pathS = malloc(strlen(pathString));
  strcpy(pathS, pathString);
  printf(1,"33333\n");
  pathCount = 0;
  int i,charIndex;
  printf(1,"44444\n");
  for(i=0; i<strlen(pathString) ; i++){
      if(pathS[i]=='\0')
      {
       char* ith = malloc(charIndex);
       strcpy(ith,pathS+i-charIndex);
       printf(1,"parsed string %s\n",ith);
       exportPathList[pathCount] = ith;
       pathCount++;
       charIndex=0;
      }
      else{
        charIndex++;
      }
  }

  return;
}

exportPathList is a global variable defined earlier in the code by char* exportPathList[32]; when using that function exportPathList[i] contains garbage. What am I doing wrong?

giladke
  • 43
  • 1
  • 4
  • When you do strlen(pathString), you only get back the length of the first string, and that's all strcpy will copy. And you'll never record the "last" string, since you stop at strlen and hence never see the terminating null. – Hot Licks Apr 14 '13 at 13:54
  • 1
    Until you don't know how many strings does the block contain, you won't be able to do it. – user35443 Apr 14 '13 at 13:55
  • 1
    You basically need to know the length of your input string, via some other means. – Hot Licks Apr 14 '13 at 13:56
  • 1
    You need to terminate your input string with a double null. Otherwise, you won't be able to know where the string array ends. – Daniel Martín Apr 14 '13 at 14:04

5 Answers5

1

First of all, since your strings are delimited by a null char, '\0', strlen will only report the size of the string up to the first '\0'. strcpy will copy until the first null character as well.

Further, you cannot know where the input string ends with this information. You either need to pass in the whole size or, for example, end the input with double null characters:

#include <stdio.h>
#include <string.h>
void parsePath(const char* pathString){
    char buf[256]; // some limit
    while (1) {
        strcpy(buf, pathString);
        pathString+=strlen(buf) + 1;
        if (strlen(buf) == 0)
            break;
        printf("%s\n", buf);
    }   
}

int main()
{
    const char *str = "aaa\0bbbb\0ccccccc\0\0";
    parsePath(str);
    return 0;
}

And you need some realloc's to actually create the array.

perreal
  • 94,503
  • 21
  • 155
  • 181
1

The answer to this SO question:

Parse string into argv/argc

deals with a similar issue, you might have a look.

You need to know how many strings are there or agree for an "end of strings". The simplest would be to have an empty string at the end:

 aaa\0bbbb\0ccccccc\0\0
                     ^^

P.S. is this homework?

Community
  • 1
  • 1
Remo.D
  • 16,122
  • 6
  • 43
  • 74
0
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAXSIZE 16

char* exportPathList[MAXSIZE] = {0};
size_t pathCount = 0;

void parsePath(char* pathString){
    char *ptop, *pend;

    ptop=pend=pathString;
    while(*ptop){
        while(*pend)++pend;
        exportPathList[pathCount++]=strdup(ptop);
        pend=ptop=pend+1;
    }
}

int main(){
    char textBlock[]= "aaa\0bbbb\0ccccccc\0";
    //size_t size = sizeof(textBlock)/sizeof(char);
    int i;

    parsePath(textBlock);
    for(i=0;i<pathCount;++i)
        printf("%s\n", exportPathList[i]);

    return 0;
 }
BLUEPIXY
  • 39,699
  • 7
  • 33
  • 70
0

The solution I've implemented was indeed adding double '\0' at the end of the string and using that in order to calculate the number of strings.

My new implementation (paths is the number of strings):

void parsePath(char* pathString,int paths){
  int i=0;  
  while (i<paths) {
    exportPathList[i] = malloc(strlen(pathString)+1);
    strcpy(exportPathList[i], pathString);
    pathString+=strlen(pathString);
    i++;
    }  
}

I'd like to thank everyone that contributed.

giladke
  • 43
  • 1
  • 4
0

My Implementation looks like this -> it follows the idea of argv and argc in a main funtion:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void){
    char **args = (char**)malloc(100*sizeof(char));
    char buff[100], input_string[100], letter;
    
    for(int i = 0; i < 100; i++){
        
        buff[i] = '\0';
        input_string[i] = '\0';
    }
    for(int i = 0; (letter = getchar())!='\n'; i++){
        input_string[i] = letter;
    }
    
    int args_num = 0;
    for(int i = 0, j = 0; i < 100;i++){
        
        if((input_string[i] == ' ')||(input_string[i]=='\0')){
            //reset j = 0
            j = 0;
            args[args_num] = malloc(strlen(buff+1));
            strcpy(args[args_num++],buff);
            for(int i = 0; i < 100; i++)buff[i] = '\0';
        }else buff[j++] = input_string[i];
        
    }    
    
    for(int i = 0; i < args_num; i++){
        printf("%s ",args[i]);
    }    
}

-> Every single word in your string can then be accessed with args[i]

John Valle
  • 13
  • 2