【问题标题】:Character arrays, and pointers how to use strtok and strcmp字符数组和指针如何使用 strtok 和 strcmp
【发布时间】:2010-09-16 15:19:44
【问题描述】:

我正在为我的操作系统类编写一个 linux shell。我已经淘汰了大部分,但我坚持简单的字符串比较。我有我能想到的一切。 strcmp 应该接受 \0 终止的字符串并返回 0 表示相等,但这似乎不起作用,甚至单步执行数组并检查每个字符也不起作用。我目前在 strcmp 中有 cmd[0] 我知道这是不对的,它需要以空值终止,但我尝试使用 strcpy 和 strcat \0 到另一个字符串。如果有人能指出我的错误,将不胜感激。

//Matthew Spiers
//CSC306

#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <iostream>
#include <unistd.h>
#include <stdlib.h>

using namespace std;

void ckCmd(char dir[]);
int main(){

    pid_t pid;
    char cdstr[4] = "cd";
    char str[50];
    char *cmd[3];
    char *pstr;
    char temp[50];
    char dir[50] = "/bin/";
    while(1){
        pid = fork();
        if(pid < 0){
            fprintf(stdout, "Fork Failed");
        }
        else if(pid == 0){
            fprintf(stdout, "\e[36m306.SH>\e[0m");
            fgets(str, 50, stdin);  
            for(int i =0; i<50; i++){
                if(str[i] == '\n'){
                    str[i] = '\0';
                }
            }
            strcpy(temp, str); // Make a copy of original string
            cmd[0] = strtok(str, " ");
            for(int i =1; i<3; i++){
                cmd[i] = strtok(NULL, " ");
            }
            strcat(dir, cmd[0]);

            cout << cmd[0];

                    pstr = strtok(temp, " ");  //pull out only first token
            //Change Directory
            if(!strcmp(pstr, "cd")){ //if first token is cd
                //either branch to a routine just change directory
                //ie branch and change directory
            }
            //ckCmd(temp);

            execlp(dir, cmd[0], cmd[1], cmd[2], NULL);
            _exit(0);
        }
        else{
            wait(NULL);
        }
    }
}

void ckCmd(char str[]){
    char *p;
    p = strtok(str, " ");
    if(p[0] == 'c'){
        chdir("new");
    }
}

    enter code here

【问题讨论】:

  • 即使你说的函数是纯C的,包含也表明你使用的是C++,所以我把标签去掉了,如果你认为合适的话,重新标记。一旦你打算使用 C++,我建议使用 std::string 并避免完全使用 strtokstrcmp,除非这是练习要求的一部分。
  • Edit 忽略了一行,没关系。
  • 充满了错误(iostreamusingnamespacecout
  • @Nikko:我不认为问题出在 C 上,有一些 C++ 独有的东西:#include &lt;iostream&gt;using namespace std;cout
  • @David :只是标准输出,可以用 C 等效项替换。

标签: c string compare


【解决方案1】:

strtok 不是可重入/线程安全的! 您应该使用 strtok 中的 RETURN 值:

p = strtok(str, " ");
    if(p[0] == 'c'){

cmd[0] = strtok(str, " ");
...
if(!strcmp(cmd[0], "cd")){

如果 p/cmd[0] 为 NULL,则会崩溃。

【讨论】:

  • 我应该只是使用 strok_r 编写自己的代码来解析字符串吗?
  • 如果您有无错误的 strtok_r 版本,请接受它,但它不是标准的。如果你没有,你可以在stackoverflow.com/questions/3375530/…上拿我的版本@
【解决方案2】:

究竟是什么不工作?你能展示一个更小的代码示例吗?

行:

strcat(dir, cmd[0]);

你知道dir是这里的目标而不是cmd[0]吗?

这条线:!strcmp(cmd[0], "cd") 本身是正确的,但不清楚你到底想做什么。你能用你的意图评论每组线吗?


更新:我建议您一次尝试太多事情。为了解决您的问题,我建议采取以下步骤:

  1. 了解strtok 的工作原理。这并不难——阅读它的手册,然后在一个带有一些字符串的单独文件中尝试它。这应该会给你一个好主意。
  2. 拆分部分代码并为它们提供预设输入(不是来自用户,也没有分叉)。查看行为符合预期的地方以及偏离的地方。

【讨论】:

  • //更改目录 if(!strcmp(cmd[0], "cd")){ //做点什么 //即分支和更改目录 } ckCmd(temp);这部分。其他一切都很好我也意识到 cmd[0] 不能正常工作,因为它没有\0。我试过:将原始字符串复制到 temp 然后剥离第一个标记,甚至在不确定 strtok 是否以 null 终止之后添加 \0。他的要求也有点模糊。目标之一是理解 strtok() 但他并没有含蓄地说要使用它。
  • 我添加了一些cmets并更改了cmd[0]
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-26
  • 1970-01-01
相关资源
最近更新 更多