【问题标题】:passing const *char to strlen() says i am passing unsigned long将 const *char 传递给 strlen() 表示我正在传递 unsigned long
【发布时间】:2020-06-17 23:43:15
【问题描述】:
char** strsep(const char* str)
{
    char** returnStrings = NULL;
    for (int i = 0; i < strlen(str); i++)
    {
        if (str[i] == ' ') returnStrings[sizeof(returnStrings)/sizeof(returnStrings[0])] = "";
        else returnStrings[sizeof(returnStrings)/sizeof(returnStrings[0])] += str[i];
    }
    return returnStrings;
}

我正在尝试制作一个可以将句子(字符串)拆分为单词数组(也是字符串)的函数,但它不会编译并显示error: implicitly declaring library function 'strlen' with type 'unsigned long (const char *)' [-Werror,-Wimplicit-function-declaration]。它说我正在输入一个 unsigned long 作为 strlen() 的参数,但我不是。 我的代码中有#include &lt;stdio.h&gt;

【问题讨论】:

  • “隐式声明”意味着您在使用函数之前忘记包含定义。是否包含定义strlen 的头文件?通常是#include &lt;string.h&gt;
  • 添加#include &lt;string.h&gt; 以修复有关strlen 的警告/错误。否则,将使用默认原型,这与使用冲突。但是,如果你这样做,你会在 your strsepreal 之间产生冲突。考虑将您的函数重命名为稍有不同的名称(例如)my_strsep
  • 这能回答你的问题吗? warning: implicit declaration of function
  • 除了警告之外,此代码表现出未定义的行为;您正在为 NULL 指针分配索引。
  • 另外,您正在评估strlen 每个 循环迭代-非常 慢。您可以执行以下操作:int len = strlen(str); 并改用 len。但是,最好在*str != 0; 上循环,如:for (; *str != 0; ++str) 并将所有str[i] 更改为*str。然后,您根本不需要调用strlen [它会在第二次/不必要的时间内传递字符串]。

标签: c strlen


【解决方案1】:

您需要#include &lt;string.h&gt; 才能获得strlen() 的正确定义。

隐式声明是过去几年的一个严重错误。

始终使用 gcc -Wall -Werror 编译。


另外,returnStrings 是一个 NULL 指针,您从不分配内存,而是尝试取消引用它。


另外,这是错误的:

returnStrings[sizeof(returnStrings)/sizeof(returnStrings[0])]

您可能在 Google 上搜索“C 获取数组的大小”并应用了该模式,但忽略了类似“这仅适用于 数组 而不适用于指针的警告。如果在指针上使用它,它会编译,但会给出不正确的结果。”


另外,这是错误的:

... += str[i]

您不能使用+= 运算符将字符附加到C 中的“字符串”。这将操纵指针,这根本不是您想要的。

【讨论】:

  • -Wall 甚至还没有开始启用“所有”警告。根据手册,它是“所有”的 easy 警告...以 -Wall -Wextra -Wfloat-equal -Wundef -Wcast-align -Wwrite-strings -Wlogical-op -Wmissing-declarations -Wredundant-decls -Wshadow 之类的开头,然后查看编译器版本的手册以找到 数十个可以使用的其他警告。尽可能多地启用它们。编译器是你的朋友。 (和 +1。)
  • 我想通了。我有另一个 .c 文件,它包含并有 string.h,但声明它的文件没有。我觉得问这个问题真的很傻。我的函数在错误的文件中声明了?
【解决方案2】:

除了您缺少&lt;string.h&gt; 的声明之外,这似乎是您的错误。

strtok() 不适合你想要的更好吗?既然你提到你想把一个句子分成一个单词数组,这些单词也是字符串?

【讨论】:

    【解决方案3】:

    只是为了解释错误信息:

    这并不是说您 unsigned long 传递给该函数。它的意思是你隐式声明了函数strlen,它应该具有unsigned long (const char *) 类型——也就是说,它应该是一个接受const char * 类型参数并且返回的函数 unisgned long。根据 C 标准,它实际上应该返回 size_t,所以在你的平台上,size_tunsigned long 可能是相同的类型。

    如果您真的想进一步了解什么是隐式声明,请参阅Are prototypes required for all functions in C89, C90 or C99?。为了(过度)简化,如果您使用尚未声明的函数(对于标准库函数,通过包含适当的标准头文件来完成),编译器会为您声明它;但是,粗略地说,它根据一组固定的规则对函数的参数和返回类型进行猜测,而且这种猜测通常是错误的。

    但是知道隐式声明是不好的就足够了,应该从你编写的任何代码中删除。

    【讨论】:

      猜你喜欢
      • 2020-05-22
      • 2018-10-15
      • 2020-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多