C字符串解析错误与strtok(),strcasecmp()

时间:2014-03-15 22:20:08

标签: c string strtok

所以我是C和整个字符串操作的新手,但我似乎无法让strtok()工作。似乎每个人都拥有相同的strtok模板:

char* tok = strtok(source,delim);
do
{
 {code}
 tok=strtok(NULL,delim);
}while(tok!=NULL);

所以我尝试使用分隔符作为空格键来执行此操作,并且似乎strtok()不仅在第一次运行后读取NULL(第一次进入while / do-while )无论字符串多大,但它似乎也破坏了源头,将源字符串转换为与tok相同的东西。

以下是我的代码片段:

char* str;
scanf("%ms",&str);
char* copy = malloc(sizeof(str));
strcpy(copy,str);
char* tok = strtok(copy," ");
if(strcasecmp(tok,"insert"))
{
 printf(str);
 printf(copy);
 printf(tok);
}

然后,这是输入“insert a b c d e f g”

的输出
aaabbbcccdddeeefffggg

“插入”似乎完全消失,我认为这是strcasecmp()的错误。另外,我想请注意,我认为strcasecmp()似乎是全部小写我的源字符串,我不介意。 Anyhoo,输入“插入插入插入”在输出中绝对没有任何结果。好像这些函数只是吃了“插入”这个词,无论它存在多少次。我可能*最终只使用了一些通过char读取字符串char的C函数,但我想尽可能避免这种情况。万分感谢,感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

使用第二段代码,您有 五个 问题:首先,scanf功能的格式是非标准的,&#39 ; 'm'应该做什么? (参见例如标准函数的here for a good reference。)

第二个问题是你在指针上使用了地址操作符,这意味着你将指针传递给指向char的指针(例如char** )到scanf函数。如您所知,scanf函数希望其参数作为指针,但由于字符串(指向字符形式或数组形式)已经是指针,因此您不必使用address-of运算符字符串参数。

第三个问题,一旦解决了上一个问题,就是指针str 未初始化。你必须记住,未初始化的局部变量确实是未初始化的,它们的值是不确定的。实际上,这意味着他们的价值看似随意。所以str会指向一些"随机"存储器中。

第四个问题是malloc调用,您在指针上使用sizeof运算符。这将返回指针的大小,而不是它指向的位置。

第五个问题是,当您对指针strtok执行copy时,copy指向的内存内容未初始化。您为它分配内存(通常为4或8个字节,具体取决于您在32或64位平台上,请参阅第四个问题),但您永远不会对其进行初始化。

所以,只有四行代码中的五个问题。这很不错! ;)

答案 1 :(得分:0)

看起来你正试图在“插入”一词后打印空格分隔的标记3次。这样做你想要的吗?

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

int main(int argc, char **argv)
{
    char str[BUFSIZ] = {0};
    char *copy;
    char *tok;
    int i;

    // safely read a string and chop off any trailing newline
    if(fgets(str, sizeof(str), stdin)) {
        int n = strlen(str);
        if(n && str[n-1] == '\n')
            str[n-1] = '\0';
    }

    // copy the string so we can trash it with strtok
    copy = strdup(str);

    // look for the first space-delimited token
    tok = strtok(copy, " ");

    // check that we found a token and that it is equal to "insert"
    if(tok && strcasecmp(tok, "insert") == 0) {
        // iterate over all remaining space-delimited tokens
        while((tok = strtok(NULL, " "))) {
            // print the token 3 times
            for(i = 0; i < 3; i++) {
                fputs(tok, stdout);
            }
        }
        putchar('\n');
    }

    free(copy);

    return 0;
}