Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

String tokenizer without using strtok()

I'm in the process of writing a string tokenizer without using strtok(). This is mainly for my own betterment and for a greater understanding of pointers. I think I almost have it, but I've been receiving the following errors:

myToc.c:25 warning: assignment makes integer from pointer without a cast
myToc.c:35 (same as above)
myToc.c:44 error: invalid type argument of 'unary *' (have 'int')

What I'm doing is looping through the string sent to the method, finding each delimiter, and replacing it with '\0.' The "ptr" array is supposed to have pointers to the separated substrings. This is what I have so far.

#include <string.h>

void myToc(char * str){
   int spcCount = 0;
   int ptrIndex = 0;

   int n = strlen(str);

   for(int i = 0; i < n; i++){
      if(i != 0 && str[i] == ' ' && str[i-1] != ' '){
         spcCount++;
      }
   }

   //Pointer array; +1 for \0 character, +1 for one word more than number of spaces
   int *ptr = (int *) calloc(spcCount+2, sizeof(char));
   ptr[spcCount+1] = '\0';
   //Used to differentiate separating spaces from unnecessary ones
   char temp;

   for(int j = 0; j < n; j++){
      if(j == 0){
         /*Line 25*/ ptr[ptrIndex] = &str[j];
         temp = str[j];
         ptrIndex++;
      }
      else{
         if(str[j] == ' '){
            temp = str[j];
            str[j] = '\0';
         }
         else if(str[j] != ' ' && str[j] != '\0' && temp == ' '){
            /*Line 35*/ ptr[ptrIndex] = &str[j];
            temp = str[j];
            ptrIndex++;
         }
      }
   }

   int k = 0;
   while(ptr[k] != '\0'){
      /*Line 44*/ printf("%s \n", *ptr[k]);
      k++;
   }
}

I can see where the errors are occurring but I'm not sure how to correct them. What should I do? Am I allocating memory correctly or is it just an issue with how I'm specifying the addresses?

like image 766
user3308219 Avatar asked May 12 '26 21:05

user3308219


2 Answers

You pointer array is wrong. It looks like you want:

char **ptr =  calloc(spcCount+2, sizeof(char*));

Also, if I am reading your code correctly, there is no need for the null byte as this array is not a string.

In addition, you'll need to fix:

while(ptr[k] != '\0'){
  /*Line 44*/ printf("%s \n", *ptr[k]);
  k++;
}

The dereference is not required and if you remove the null ptr, this should work:

for ( k = 0; k < ptrIndex; k++ ){
  /*Line 44*/ printf("%s \n", ptr[k]);
}
like image 119
dohashi Avatar answered May 15 '26 10:05

dohashi


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

void myToc(char * str){
    int spcCount = 0;
    int ptrIndex = 0;

    int n = strlen(str);

    for(int i = 0; i < n; i++){
        if(i != 0 && str[i] == ' ' && str[i-1] != ' '){
            spcCount++;
        }
    }

    char **ptr = calloc(spcCount+2, sizeof(char*));
    //ptr[spcCount+1] = '\0';//0 initialized by calloc 
    char temp = ' ';//can simplify the code

    for(int j = 0; j < n; j++){
        if(str[j] == ' '){
            temp = str[j];
            str[j] = '\0';
        } else if(str[j] != '\0' && temp == ' '){//can omit `str[j] != ' ' &&`
            ptr[ptrIndex++] = &str[j];
            temp = str[j];
        }
    }

    int k = 0;
    while(ptr[k] != NULL){//better use NULL
        printf("%s \n", ptr[k++]);
    }
    free(ptr);
}

int main(){
    char test1[] = "a b c";
    myToc(test1);
    char test2[] = "hello world";
    myToc(test2);
    return 0;
}
like image 29
BLUEPIXY Avatar answered May 15 '26 12:05

BLUEPIXY



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!