I found strtok function has some trick during you pass the same string to another function, code as follows:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void split_redirect(char input[80], int switch_bit);
void split_background(char *split_cmd);
void split_background(char *split_cmd){
char *tmp = strchr(split_cmd, '&');
if (tmp == NULL){ }
else{
char *command = strtok(split_cmd,"&");
while(command!=NULL){
// char *command_next = strtok(NULL,"&");
printf("command=[%s]\n",command);
if((strchr(command,'>')!=NULL)||(strchr(command,'<')!=NULL)){
split_redirect(command,0);
}
// command = command_next;
command = strtok(NULL,"&");
printf("command_next=[%s]\n",command);
}
}
}
void split_redirect(char input[80], int switch_bit){
char *tmp ,*tmp2;
tmp = strchr(input, '>');
tmp2 = strchr(input, '<');
if (tmp == NULL && tmp2 == NULL){ }
else if(tmp2 == NULL && tmp !=NULL){
// single >
char *copy = (char *)malloc(sizeof(input));
strcpy(copy,input);
char *tmp = strtok(copy,">");
char *cmd = tmp;
tmp = strtok(NULL,"\0");
if (strchr(tmp,'>')==NULL){
char *file_name = strtok(tmp," ");
}
else{
free(copy);
copy=NULL;
}
}
else{ }
}
void main(int argc,char *argv[]){
// char *cmd2 = "cmd1 > txt & cmd2 > txt2" // -> each char can't be change, so strotk this string will get seg fault. Modify token to '\0' is illegal. in .RDATA
char cmd[80] = "cmd1 > txt & cmd2 > txt &";
split_background(cmd);
}
Expect output:
command=[cmd1 > txt ]
command_next=[ cmd2 > txt ]
The output:
command=[cmd1 > txt ]
command_next=[(null)]
Why when I pass this string to another function will cause the rest of string becomes null string? When I unmark char *command_next = strtok(NULL,"&"); and replace command = strtok(NULL,"&"); to command = command_next; It will print the rest of string as my expectation. Is it relate to how strtok store that string by static memory?
Read the manual: The
strtokfunction changes the original string and overwrites the delimiter characters with null bytes. The rest of the string doesn’t “become null string”, but you have to resume the rest of the string one after the last found token.It’s probably best to use
strtokidiomatically to extract all tokens, and then process those tokens individually.