I created a function to split a string with comma.
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
char splitted_line[8][50];
void split(char *line){
printf("line 9\n");
char *part = strtok(line, ",");
printf("line 11\n");
for(int i=1; i<8; i++){
strcpy(splitted_line[i], part);
printf("%s\n", splitted_line[i]);
part = strtok(NULL, ",");
}
}
int main(){
char *line = "123,456,789";
split(line);
return 0;
}
but the result after running is :
line 9
Segmentation fault (core dumped)
it seems the problem is in char *part = strtok(line, ","); but I don't know what's that.
strtok() will modify passed original string directly.
You must not modify string literals.
char *line = "123,456,789";
should be modifyable array
char line[] = "123,456,789";
Also don't forget to check if part is not NULL before doing strcpy(splitted_line[i], part);.
I get a segmentation fault the second time malloc runs:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int keywords_init(char *str, char ***str_arr);
int main(void) {
char str[] = "keyword1,keyword2,keyword3";
char **str_arr = NULL;
int arr_elements;
arr_elements = keywords_init(str, &str_arr);
return 0;
}
int keywords_init(char *str, char ***str_arr) {
int i;
char *pch;
/* String break */
pch = strtok(str, ",");
for (i = 0; pch != NULL; i++) {
*str_arr = realloc (*str_arr, (i+1)*sizeof(char *));
*str_arr[i] = malloc (strlen(pch) + 1);
strcpy(*str_arr[i], pch);
printf("%d: %s\n", i, pch);
pch = strtok (NULL, ",");
}
return i;
}
What confuses me is that if I don't pass the address of str_arr to keywords_init and use a double pointer instead of a triple one in keywords_init it works just fine.
You're getting bitten by operator precedence/associativity - change both occurrences of:
*str_arr[i]
to:
(*str_arr)[i]
Hey I'm having problems with my code I get creating the tokens and have it adding it add the tokens to a 2d array but it doesn't work correctly. Any idea why.
/* strtok example */
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] ="This a sample string";
char * st[4][0];
char * pch;
int i;
printf ("Splitting string \"%s\" into tokens:\n",str);
pch = strtok (str," ");
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, " ");
for(i=0;i<4;i++)
{
st[i][0]=pch;
}
}
print(st, i);
return 0;
}
void print(char st[4][0], int i)
{
for(i=0;i<4;i++)
{
printf("%d - %s",i ,st[i][0]);
}
}
char * st[4][0];
You are allocating an array of zero length. later you try to access the first element, which is non-existent, and therefore you get undefined behaviour.
I cannot see why this array has two dimensions anyway. You only access the first element of the second dimension, why not:
char * st[4];
??
To be more precise I don't understand the usage of this variable at all. Why do you write the same value in all four elements?
There are a number of problems: compare with this code:
/* strtok example */
#include <stdio.h>
#include <string.h>
void print(char *st[4]) // Fixed parameter type
{
int i; // i is a local counter
for(i=0;i<4;i++)
{
printf("%d - %s\n",i ,st[i]);
}
}
int main ()
{
char str[] ="This a sample string";
char * st[4]; // Corrected array definition
char * pch;
int i=0; // Initialise counter i to 0
printf ("Splitting string \"%s\" into tokens:\n",str);
pch = strtok (str," ");
while (pch != NULL)
{
st[i]=pch; // Store string before overwriting pch, and only store in a single location
printf ("%s\n",pch);
pch = strtok (NULL, " ");
i++; // increment i inside loop
}
print(st);
return 0;
}
I have a problem with strtok() - it does not return the input as expected.
void parse_input(const char *input,unsigned char *ctext, int mlen){
char * str = strdup(input);
char * pch = strtok(str,"-");
while (pch != NULL)
{
ctext[mlen] = (int) pch;
pch = strtok (NULL, "-");
mlen++;
}
On input like 1-2-3-4 I would want it to fill ctext with [1,2,3,4].
That doesn't work, however.
What am I doing wrong? Any help appreciated.
ctext[mlen] = (int) pch;
That stores the numeric value of the pointer, whereas you really want the character pointed to by the pointer. Time to read a good article/book/tutorial on pointers.
ctext[mlen] = *pch;
is what you're looking for.
You want to get the character in the first byte of pch -- not the address of pch
ctext[mlen] = *pch;
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void parse_input(const char *input,unsigned char *ctext[], int *mlen){
char * str = strdup(input);
char * pch = strtok(str,"-");
while (pch != NULL){
ctext[(*mlen)++] = (unsigned char*)pch;
pch = strtok (NULL, "-");
}
}
int main(void){
unsigned char *ctext[16];
int mlen=0;
int i;
parse_input("1-2-3-4", ctext, &mlen);
printf("[ ");
for(i=0;i<mlen;++i){
printf("%s", ctext[i]);
if(i<mlen -1)
printf(", ");
}
printf(" ]\n");
//free(ctext[0]);
return 0;
}
I need to divide a C string into tokens. I thought that strtok will be my best try, but I'm getting very strange results...
Here is my test program. In this example I will get 3 tokens with "##" separator but when I try to work with the ones I supposedly had copied, only the third one is shown correctly.. the other two look corrupted or something... I don't know... ?
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#define TAM 3 //elements
char** aTokens(char* str, char* delimitador)
{
char* pch;
char** tokens;
int i = 0;
tokens = (char**)malloc(sizeof(char*)*TAM);
pch = strtok(str, delimitador);
while(pch != NULL)
{
tokens[i] = (char*)malloc((sizeof(strlen(pch))+1) * sizeof(char));
strcpy(tokens[i], pch);
pch = strtok(NULL, delimitador);
i++;
}
return tokens;
}
int main ()
{
char str[] = "30117700,1,TITULAR,SIGQAA070,1977/11/30,M,1,14000,0.00,6600.00,10.00,2011/09/01,2012/09/01,0|17,0.00,NO,0,0,0.00, ,##30117700,1,TITULAR,SIGQAA070,1977/11/30,M,1,14000,0.00,6600.00,10.00,2011/09/01,2012/09/01,0|17,0.00,NO,0,0,0.00, ,##30117700,1,TITULAR,SIGQAA070,1977/11/30,M,1,14000,0.00,6600.00,10.00,2011/09/01,2012/09/01,0|17,0.00,NO,0,0,0.00, ,";
char** tokens;
int i;
tokens = aTokens(str, "##");
for(i = 0; i<TAM; i++)
printf("%d -- %s\n", strlen(tokens[i]), tokens[i]);
//Clean
//for(i = 0; i<TAM; i++)
//free(tokens[i]);
//free(tokens);
return 0;
}
output with GCC on Linux:
13 -- 30117700,1,T <---- ?
13 -- 30117700,1,T <----- ?
115 -- 30117700,1,TITULAR,SIGQAA070,1977/11/30,M,1,14000,0.00,6600.00,10.00,2011/09/01,2012/09/01,0|17,0.00,NO,0,0,0.00, ,
I have commented the "clean" section because it provides lots of runtime error too ... :(
Help please!!
I think you are slightly confused on how strtok works.
For the most part, you've got it right. However, the string of separator characters that is given to strtok is not used as a string per se, but it used more like an array of characters, and strtok only cares about these individual characters. So calling strtok with the string "#" is exactly the same as giving it "##". In order to tokenize your string correctly, you need to decide on a single separator character to use, or use a different (perhaps custom) tokenizer function that can handle multi-character separators..
The following line isn't correct. sizeof(strlen(..)) will be 4 (in a 32-bit app) regardless of the length of the string.
tokens[i] = (char*)malloc((sizeof(strlen(pch))+1) * sizeof(char));
It should probably be:
tokens[i] = (char*)malloc((strlen(pch)+1) * sizeof(char));
Standard implementation of strtok:
/* strtok example */
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] = "30117700,1,TITULAR,SIGQAA070,1977/11/30,M,1,14000,0.00,6600.00,10.00,2011/09/01,2012/09/01,0|17,0.00,NO,0,0,0.00, ,##30117700,1,TITULAR,SIGQAA070,1977/11/30,M,1,14000,0.00,6600.00,10.00,2011/09/01,2012/09/01,0|17,0.00,NO,0,0,0.00, ,##30117700,1,TITULAR,SIGQAA070,1977/11/30,M,1,14000,0.00,6600.00,10.00,2011/09/01,2012/09/01,0|17,0.00,NO,0,0,0.00, ,";
char * pch;
printf ("Splitting string \"%s\" into tokens:\n",str);
pch = strtok (str,"#");
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, "#");
}
return 0;
}