c++,string,compare,nocase,for copy

本文介绍了在C++中如何实现字符串的大小写忽略比较。提供了多种方法,包括使用标准库函数转换大小写后再比较、利用Boost库提供的工具函数、自定义字符特性类等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

总结:如何在c++中进行大小写忽略的比较,基于std:string 

ref1ref2ref3


问题由来:

标准字符 (typedef basic_string<char> string)由于国际化过程中,没有实现每一种语言的大小写转换函数,也没要提供基于ansi字符的大小写忽略比较。


解决方案1:先转换大小写再比较

策略1. std method

C++ — Convert string to upper/lower case


To convert an std::string to upper case you can use the following:

#include <algorithm>
#include <string>
…
std::string data = “Abc”;
std::transform(data.begin(), data.end(),
data.begin(), ::toupper);

For converting to lower case, you need to replace::toupper with ::tolower.

If you really hate tolower(), here's an alternative:

char easytolower(char in){
  if(in<='Z' && in>='A')
    return in-('Z'-'z');
  return in;
} 

std::transform(data.begin(), data.end(), data.begin(), easytolower);

策略2. boost method

There is a Boost string algorithm for this:

#include <boost/algorithm/string.hpp>    

std::string str = "HELLO, WORLD!";
boost::algorithm::to_lower(str);

解决方案2:直接比较

策略1

Boost includes a handy algorithm for this:

#include <boost/algorithm/string.hpp>

std::string str1 = "hello, world!";
std::string str2 = "HELLO, WORLD!";

if (boost::iequals(str1, str2))
{
    // Strings are identical
}
策略2

Take advantage of the standard char_traits. Recall that a std::string is in fact a typedef for std::basic_string<char>, or more explicitly,std::basic_string<char, std::char_traits<char> >. The char_traits type describes how characters compare, how they copy, how they cast etc. All you need to do is typedef a new string over basic_string, and provide it with your own customchar_traits that compare case insensitively.

struct ci_char_traits : public char_traits<char> {
    static bool eq(char c1, char c2) { return toupper(c1) == toupper(c2); }
    static bool ne(char c1, char c2) { return toupper(c1) != toupper(c2); }
    static bool lt(char c1, char c2) { return toupper(c1) <  toupper(c2); }
    static int compare(const char* s1, const char* s2, size_t n) {
        while( n-- != 0 ) {
            if( toupper(*s1) < toupper(*s2) ) return -1;
            if( toupper(*s1) > toupper(*s2) ) return 1;
            ++s1; ++s2;
        }
        return 0;
    }
    static const char* find(const char* s, int n, char a) {
        while( n-- > 0 && toupper(*s) != toupper(a) ) {
            ++s;
        }
        return s;
    }
};

typedef std::basic_string<char, ci_char_traits> ci_string;


策略3

bool caseInsensitiveStringCompare(const string& str1, const string& str2) {
    if (str1.size() != str2.size()) {
        return false;
    }
    for (string::const_iterator c1 = str1.begin(), c2 = str2.begin(); c1 != str1.end(); ++c1, ++c2) {
        if (tolower(*c1) != tolower(*c2)) {
            return false;
        }
    }
    return true;
}
策略5

The trouble with boost is that you have to link with and depend on boost. Not easy in some cases (e.g. android).

And using char_traits means all your comparisons are case insensitive, which isn't usually what you want.

This should suffice. It should be reasonably efficient. Doesn't handle unicode or anything though.

bool iequals(const string& a, const string& b)
{
    unsigned int sz = a.size();
    if (b.size() != sz)
        return false;
    for (unsigned int i = 0; i < sz; ++i)
        if (tolower(a[i]) != tolower(b[i]))
            return false;
    return true;
}
策略6

ere is a method of doing this, although it does transforming the strings, and is not Unicode friendly, it should be portable which is a plus:

bool caseInsensitiveStringCompare( const std::string& str1, const std::string& str2 ) {
    std::string str1Cpy( str1 );
    std::string str2Cpy( str2 );
    std::transform( str1Cpy.begin(), str1Cpy.end(), str1Cpy.begin(), ::tolower );
    std::transform( str2Cpy.begin(), str2Cpy.end(), str2Cpy.begin(), ::tolower );
    return ( str1Cpy == str2Cpy );
}

<think>我们正在处理一个关于TCL字符串比较的问题。根据用户的问题,他想知道在TCL脚本中如何比较两个字符串。根据引用[1]和[2],TCL中字符串比较有两种推荐方法:stringcomparestring equal。引用[1]提到:尽管可以直接使用数学表达式(>、<和==)进行字符串比较,但从代码风格和执行效率的角度,string comparestringequal更为高效。通过timing命令测试,string equal耗时最短。引用[2]详细说明了这两个命令的用法:-string compare:如果两个字符串相同则返回0,不同则返回-1(或1,取决于第一个字符串是小于还是大于第二个字符串)。- stringequal:如果两个字符串相同则返回1,不同则返回0。此外,引用[2]还提供了代码示例:使用string compare:sets1abcsets2abdif{[string compare$s1 $s2] ==0} {puts"passed"} else{puts "failed"}使用string equal:set s1 abcset s2 abdif {[stringequal $s1$s2]}{puts "passed"}else {puts"failed"}因此,我们可以向用户推荐这两种方法,并说明它们的区别。另外,引用[3]中提到了字符串比较命令,并再次强调了stringcomparestring equal的使用。根据以上信息,我们可以这样回答用户:在TCL中,比较两个字符串的推荐方法是使用`stringcompare`或`string equal`命令。这两种方法比直接使用数学比较运算符(如`==`、`<`、`>`)更高效且更安全。具体用法:1.`stringequal`:当两个字符串相等时返回1,否则返回0。示例:if{[string equal$str1 $str2]} {#字符串相等时的操作}2. `string compare`:比较两个字符串,如果两个字符串相等则返回0;如果第一个字符串在字典顺序上小于第二个字符串,则返回-1;如果大于,则返回1。示例:if {[stringcompare $str1$str2]==0}{#字符串相等时的操作}注意:直接使用`if{$str1== $str2}`进行字符串比较在TCL中是可行的,但可能会导致意外的结果(例如当字符串中包含特殊字符时),并且效率较低。因此,建议使用上述两个命令。另外,引用[1]中提到通过`timing`命令测试,`string equal`的执行时间最短,所以如果仅需判断相等,推荐使用`stringequal`。下面是一个完整的示例:```tclsetstr1 "hello" setstr2"world" #使用string equal比较if {[stringequal $str1$str2]}{puts "字符串相等" }else {puts"字符串不相等" }#使用stringcompare比较setresult[stringcompare $str1$str2]if {$result ==0} {puts"字符串相等"} elseif{$result<0}{puts "str1小于str2"} else{puts "str1大于str2"} ```在这个示例中,我们展示了两种比较方法。第一种只判断相等,第二种可以判断相等以及大小关系。根据引用[1][2][3],我们总结:在TCL中进行字符串比较,优先使用`string equal`(仅判断相等)或`string compare`(判断相等和大小关系)。最后,我们生成相关问题。</think>### TCL 字符串比较方法详解 在 TCL 脚本中,推荐使用专门的字符串比较命令进行字符串比较,主要有两种高效可靠的方法: #### 1. **`string equal` 命令**(推荐) 当需要判断两个字符串是否完全相同时,`string equal` 是最优选择: ```tcl set str1 "apple" set str2 "Apple" # 比较字符串是否相等(区分大小写) if {[string equal $str1 $str2]} { puts "字符串相同" } else { puts "字符串不同" } ``` - **返回值**:相同返回 `1`,不同返回 `0` - **特点**:执行效率最高[^1],语法简洁 - **大小写敏感控制**: ```tcl # 不区分大小写比较 if {[string equal -nocase $str1 $str2]} { puts "忽略大小写后相同" } ``` #### 2. **`string compare` 命令** 当需要获取字典序比较结果时使用: ```tcl set result [string compare $str1 $str2] switch $result { -1 { puts "str1 在字典序中小于 str2" } 0 { puts "字符串完全相同" } 1 { puts "str1 在字典序中大于 str2" } } ``` - **返回值**: - `-1`:第一个字符串小于第二个 - `0`:字符串相同 - `1`:第一个字符串大于第二个 #### 不推荐方法:直接使用比较运算符 虽然 TCL 允许使用 `==`、`!=`、`>`、`<` 等运算符,但存在风险: ```tcl # 可能产生意外结果(特别是包含特殊字符时) if {$str1 == $str2} {...} # 不推荐 ``` **缺点**: - 需要手动用双引号包裹变量[^2] - 对空字符串或特殊字符处理可能不一致 - 执行效率低于专用命令[^1] #### 性能对比验证 通过 `time` 命令测试不同方法的耗时: ```tcl set a "test_string" set b "test_string" puts [time {string equal $a $b} 10000] ;# 平均耗时最短 puts [time {string compare $a $b} 10000] puts [time {if {$a == $b} {}} 10000] ;# 相对最慢 ``` 测试结果通常显示 `string equal` 性能最优[^1]。 > **最佳实践建议**: > 1. 仅需判断相等性时 → 使用 `string equal` > 2. 需要字典序结果时 → 使用 `string compare` > 3. 避免直接使用比较运算符 > 4. 处理用户输入时始终用双引号包裹变量[^2]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值