【问题标题】:g++ error: ‘stricmp’ was not declared in this scope (but OK for 'strcmp')g++ 错误:“stricmp”未在此范围内声明(但“strcmp”可以)
【发布时间】:2009-11-23 17:41:38
【问题描述】:

我正在尝试编译以下非常非常简单的源代码:

#include <cstring>
// #include <string.h>
// using namespace std;

class Helper {
public:
    int cStringsAreEqual(const char *s1, const char *s2) {
        return stricmp(s1, s2);
    }
};

...但我收到以下错误消息:

   g++ error: ‘stricmp’ was not declared in this scope

但是,当我使用 strcmp() 而不是 stricmp() 时,一切都很好!

这里有什么问题?允许strcmp()的时候不应该允许stricmp()吗?

Sureley,这一切都可以在不使用 strcmp/stricmp 的情况下以更好的方式编写。

但这不是重点。

我正在移植一个软件——它大量使用了对 stricmp() 的调用。如果可能的话,我想避免将每次调用更改为 stricmp 所需的所有努力。

对此的任何帮助将不胜感激!

顺便说一句:我正在使用带有 g++ v4.4.1 的 Ubuntu karmic OS (v9.10)。

顺便说一句:如您所见,我还使用 '#include string.h' 或 'namespace std' 进行了一些试验,但没有任何帮助。

【问题讨论】:

  • 考虑到 stricmp 和 strcmp 不一样(后者区分大小写),您可能需要在更改它们之前犹豫一下。
  • 知道他们不一样。这就是为什么我想使用 stricmp 而不是 strcmp
  • 还要注意&lt;string.h&gt;&lt;cstring&gt; 不完全是一些。这不是您的问题的原因,但您需要编写 std::strcmp(或 std::strcoll)而不是假设名称已导入全局命名空间。

标签: c++ g++


【解决方案1】:

试试strcasecmp()。这是它的manual page。符合 4.4BSD 和 POSIX.1-2001。

【讨论】:

  • 这是一个选择。 strcasecmp() 似乎具有相同的参数。因此,创建一个进行全局更改的小型 perl 脚本应该不难。非常感谢!
  • 没问题。另请查看 Mark Rushakoff 关于区域设置如何影响此功能的评论。
  • 请注意 strcasecmp 取决于您的语言环境。因此 strcasecmp("div","DIV") 不会在土耳其语言环境中返回 0(小写 I 是 ı)。这意味着您的字符串来自哪里很重要:-(。还有其他语言的其他示例。您可能会为外国用户破坏您的程序。
【解决方案2】:

stricmp is neither POSIX nor ANSI,因此如果您的编译器或标准库严格遵守 POSIX 或 ANSI 标准库函数(GCC 套件可能就是这种情况),是否允许 strcmp 并不重要。

【讨论】:

  • 这很复杂,因为“区分大小写”的概念可能取决于您的语言环境或操作系统。查看这个问题的一些答案:stackoverflow.com/questions/11635/…
  • 我在带有 Cygwin 的 Windows 7 上使用 Eclipse CDT,并且在那里接受 stricmp。在我的 Linux 机器上,不接受 GCC。这是否意味着 Cygwin 中包含的编译器不是 POSIX 或 ANSI?
【解决方案3】:

为其添加一个定义,以便在您正在寻找的平台上用 strcasecmp 覆盖 stricmp。

#ifdef _IPHONE <- your platform define here
#define stricmp strcasecmp
#define strnicmp strncasecmp
#endif

那么你可以一直使用 stricmp。

【讨论】:

  • 我们把这个放在哪里
  • 只需将它放在标题中或与任何其他预处理器指令(ifdefs/defines)一起放在顶部:cplusplus.com/doc/tutorial/preprocessor #define _IPHONE 将切换到上面的用法减去“
【解决方案4】:

如果您有 Boost,请在 &lt;boost/algorithm/string/predicate.hpp&gt; 中使用 boost::algorithm::iequals(s1, s2, std::locale::classic())(或者如果您想要区域设置敏感度,则不要使用区域设置)。它适用于 C 字符串、std::[w]stringvector&lt;char&gt; 等。

【讨论】:

    【解决方案5】:

    如果需要,很容易自己制作......

    int my_stricmp (const char *s1, const char *s2)
    {
        while (*s1 != 0 && *s2 != 0)
        {
            if (*s1 != *s2 && ::toupper (*s1) != ::toupper(*s2))
            {
                return -1;
            }
            s1++;
            s2++;
        }
        return (*s1 == 0 && *s2 == 0) ? 0 : -1;
    }
    

    【讨论】:

    • s1 的排序晚于s2 时,如何返回正值?还是打算与std::strcmp() 有不同的界面?
    • 解决了@TobySpeight 指出的问题。如果逻辑也更正了。
    • CAVEAT:对::toupper 的调用是特定于区域设置的。根据您运行它的位置,您可能会得到不同的结果。考虑改用语言环境感知覆盖。
    • @Jesse,您提出的更改相当大,因此被审阅者拒绝。您可能想添加一些解释并将其转换为正确的答案。
    • @Toby:审稿人该死。如果您发布了不正确的答案,您应该修复它(如果需要,您自己),或者删除它,或者至少将其标记为不正确。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多