当前位置: 首页 > 知识库问答 >
问题:

strtok()、strcasecmp()的C字符串分析错误

卫成和
2023-03-14

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

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

因此,我尝试使用分隔符作为空格键来执行此操作,并且strtok()似乎不仅在第一次运行(while/do-while的第一个条目)后读取NULL,无论字符串有多大,而且似乎还会破坏源字符串,将源字符串变成与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

“Insert”似乎完全消失了,我认为这是strcasecmp()的错误。另外,我想指出的是,我意识到strcasecmp()似乎都是小写的源字符串,我不介意。总之,输入“insert-insert”在输出中绝对不会产生任何结果。这就好像那些函数吃掉了单词“insert”,不管它出现了多少次。我可能最终只使用一些逐字读取字符串的C函数,但如果可能的话,我希望避免这种情况。谢谢大家,我很感谢你们的帮助。

共有2个答案

慕容劲
2023-03-14

看起来您要在单词“insert”后打印三次空格分隔的标记。这是你想要的吗?

#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;
}
章学义
2023-03-14

对于第二段代码,您有五个问题:第一个是您的scanf函数的格式是非标准的,'m'应该做什么?(例如,请参阅此处以获取标准函数的良好参考。)

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

第三个问题是,一旦修复了前一个问题,指针str就未初始化。您必须记住,未初始化的局部变量实际上是未初始化的,它们的值是不确定的。实际上,这意味着它们的值似乎是随机的。因此,str将指向一些“随机”内存。

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

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

因此,只有四行代码中有五个问题。太好了!;)

 类似资料:
  • 我有一个输入表单,允许某人键入unicode字符。所以它可能是类似于“嘿,uF32A怎么了?如果我得到这个字符串,它将有一个子字符串“\uF32A”,我如何将其转换为字符“\uF32A”?

  • 我将字符串作为解析器规则而不是词法分析器,因为字符串可能包含带有表达式的转义,例如。 这不起作用,因为

  • 本文向大家介绍php字符比较函数similar_text、strnatcmp与strcasecmp用法分析,包括了php字符比较函数similar_text、strnatcmp与strcasecmp用法分析的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了php字符比较函数similar_text、strnatcmp与strcasecmp用法。分享给大家供大家参考。具体如下: ① simil

  • 我需要解析“txf”格式的数据文件。这些文件可能包含 1000 多个条目。由于格式像JSON一样定义得很好,我想做一个像JSON这样的通用解析器,它可以序列化和解串化txf文件。 与JSON相反,标记没有办法识别对象或数组。如果一个带有相同标签的条目出现,我们需要把它看作一个数组。 标记对象的开始。 标记对象的成员 标记对象的结尾 下面是一个示例“txf”文件 我能够使用NSScanner创建通用

  • 本文向大家介绍C#按特定字符分割字符串,包括了C#按特定字符分割字符串的使用技巧和注意事项,需要的朋友参考一下 示例            

  • 给定一个字符串,例如“John Doe, USA,男性”,我将如何使用逗号作为分隔符来拆分字符串。目前我使用提升库并设法拆分,但白色行间距会导致问题。 例如,上面的字符串一旦拆分成一个向量,只包含“John”,而不包含其余部分。 更新 这是我目前正在使用的代码 迭代后,我只得到名字,而不是完整的细节