算法19:实现 char* strtok(char* str, const char* delimeter)

本文介绍了一个使用C++实现的strtok函数,该函数能够根据指定的分隔符分割字符串,并通过静态变量来跟踪分割过程。文章提供了完整的源代码及测试示例,帮助读者理解如何正确使用strtok进行字符串分割。

算法分析

strtok是用来分隔字符串,首次使用strtok时,str指向待分隔的字符串;后续调用要将str置为NULL,直至返回值为NULL。
因此,需要一个static变量指向str变量。

c++代码

//str:待分隔的源字符串
//delimeter:分隔符
char* strtok(char* str, const char* delimeter)
{
    //静态变量,指向带分隔的源字符串
    static char* staticStr = NULL;
    //指向分隔符的指针
    const char* pDelimeter = NULL;
    //返回值
    char* pRetStr = NULL;
    //标志位
    bool bFind = false;

    if(str != NULL)
    {
        staticStr = str;
    }

    if(*staticStr == '\0')
    {
        return NULL;
    }

    pRetStr = staticStr;
    while(*staticStr != '\0')
    {
        for(pDelimeter = delimeter; *pDelimeter != '\0';pDelimeter++ )
        {
            if(*pRetStr == *pDelimeter)
            {
                pRetStr++;
                break;
            }

            if(*staticStr == *pDelimeter)
            {
                bFind = true;
                *staticStr = '\0';
            }
        }

        staticStr++;

        if(bFind)
        {
            break;
        }
    }

    return pRetStr;

}

测试代码

int _tmain(int argc, _TCHAR* argv[])
{
    char data[20] = "salfgdfogffhe";

    char* result = strtok(data,"gd");
    cout<<result<<endl;

    while(result != NULL)
    {
        result = strtok(NULL,"gd");
        if(result != NULL)
        {
            cout<<result<<endl;
        }
    }

    return 0;
}
关于这个题我给你代码 你帮我写报告文档,包括每道习题要求、实现思路/步骤、void shell_execv() { char *cmd_str = (char*)malloc(sizeof(char) * MAX_STR); /*输入命令*/ if (cmd_str == NULL) { printf("malloc cmd_str mem is failed\n"); return; } char *cmd_str_copy = (char*)malloc(sizeof(char) * MAX_STR); /*输入命令副本,防止使用strtok获取token而破坏*/ if (cmd_str_copy == NULL) { printf("malloc cmd_str_copy mem is failed\n"); return; } const char * s = " "; /*获取token的分隔符*/ enum COMMAND cmd; /*枚举命令变量*/ char *token = (char*)malloc(sizeof(char) * MAX_STR); /*分割token变量*/ if (token == NULL) { printf("malloc token mem is failed\n"); return; } int exR; /*错误码*/ char *args[MAX_ARG]; /*执行execve函数的命令参数*/ char *envs[] = {NULL}; /*执行execve函数的环境变量,默认NULL*/ int pid = -1; /*进程pid*/ int len = 0; /*字符串长度*/ int i = 0; int j = 0; char *pipe_path = "/tmp/myfifo"; /*共享管道名*/ int fd = 0; /*管道句柄*/ char buf[MAX_STR]; /*读取数据缓冲区*/ int read_num; /*从stdin中读取的字节数*/ while (1) { sleep(0.1); printf("\n"); printf("*********************************************\n"); printf("***********usage: echo <content>************\n"); printf("*******usage: execv <path> <params...>*******\n"); printf("*****************usage: exit*****************\n"); printf("*********************************************\n"); printf("\n"); printf("input your command : "); fgets(cmd_str, MAX_STR, stdin); /*获取数据*/ if (cmd_str == NULL) { printf("input error cmd is NULL\n"); exit(-1); } /*消除获取字符串得到的'\n'*/ len = strlen(cmd_str); if (len > 0 && cmd_str[len - 1] == '\n') { cmd_str[len - 1] = '\0'; } strcpy(cmd_str_copy, cmd_str); token = strtok(cmd_str_copy, s); /*匹配字符串*/ if (strcmp(cmd_str, "exit") == 0) { cmd = EXIT; } else if (strcmp(token, "execv") == 0) { cmd = EXECV; } else if (strcmp(token, "echo") == 0) { cmd = ECHO; } else { cmd = NO_CURRENT_CMD; } /*对对应操作进行处理*/ switch (cmd) { case ECHO: /*打印等效echo*/ while (token != NULL) { token = strtok(NULL, " "); if (token != NULL) { printf("%s ", token); } } printf("\n"); break; case EXECV: /*执行命令*/ /*对于命令进行拆分,得到命令和命令参数*/ while (token != NULL && i < MAX_ARG) { token = strtok(NULL, " "); args[i] = token; i++; } /*创建进程*/ pid = fork(); if (pid == 0) { exR = execve(args[0], args, NULL); if (exR == -1) { printf("\nerror start execv son program\n"); _exit(-1); /*失败后回收进程*/ } } else if (pid > 0) { /*增加延迟机制,方便判断子进程是否正确加载*/ sleep(1); if (waitpid(pid, NULL, WNOHANG) > 0) { printf("The process does not exist\n"); break; } else { printf("create son ps is success \n"); } /*打开匿名管道*/ fd = open(pipe_path, O_RDONLY); if (fd < 0) { printf("no file"); break; } /*读取数据*/ while ((read_num = read(fd, buf, MAX_STR)) > 0) { if (read_num > 0 && buf[read_num - 1] == '\n') { buf[read_num - 1] = '\0'; } /*接受到停止指令,杀死子进程程序*/ if (strcmp(buf, "stop") == 0) { kill(pid, SIGKILL); if (waitpid(pid, NULL, WUNTRACED) < 0) { printf("son pid is exit failed\n"); } else { printf("son pid is exit \n"); } break; } write(STDOUT_FILENO, "print: ", sizeof("print: ")); write(STDOUT_FILENO, buf, read_num); printf("\n"); } } else { printf("create ps failed \n"); } /*重置pid和i变量*/ pid = -1; i = 0; break; case EXIT: /*退出shell进程*/ return; default:/*输入命令错误*/ printf("no command is uncorrect!\n"); break; } } /*释放堆*/ free(cmd_str); free(cmd_str_copy); free(token); close(fd); } int main() { shell_execv(); return 0; }
08-09
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值