-2

请注意,我不是在问在 C++ 中将小写字母转换为大写字母的方法是什么,而是我想知道下面代码(Upper1 和 Upper2)中这两种方法中的哪一种比另一种更好,原因是什么,编程明智。

#include <string>
#include <iostream>
#include <locale> //Upper2 requires this module

using namespace std;

void Upper1(string &inputStr);
void Upper2(string &inputStr);

int main(){

    string test1 = "ABcdefgHIjklmno3434dfsdf3434PQRStuvwxyz";
    string test2 = "ABcdefgHIjklmnoPQRStuvwxyz";

    Upper1(test1);
    cout << endl << endl << "test1 (Upper1): ";
    for (int i = 0; i < test1.length(); i++){
        cout << test1[i] << " ";
    }


    Upper2(test2);
    cout << endl << endl << "test2 (Upper2): ";
    for (int i = 0; i < test2.length(); i++){
        cout << test2[i] << " ";
    }

    return 0;
}

void Upper1(string &test1){

    for (int i = 0; i < 27; i++){ 
        if (test1[i] > 96 && test1[i] <123){ //convert only those of lowercase letters
            test1[i] = (char)(test1[i]-(char)32);
        }

    }
}

void Upper2(string &test2){

    locale loc;

    for (size_t i=0; i<test2.length(); ++i)
        test2[i] = toupper(test2[i],loc);
}
4

3 回答 3

3

两种提议的解决方案之间的主要区别在于 Upper2这种工作方式,无论平台如何;Upper1 对编码做出假设,并且不适用于我所知道的任何现代平台。(它假定 ASCII,而 ASCII 出于所有意图和目的,已经死了。)

当然,两者都不起作用,原因有两个:首先,大多数现代机器使用多字节编码 (UTF-8),因此您不能一次将字符串从低字节转换为高字节。第二个是因为一般来说不存在下到上的一对一关系:经典的例子是'ß',它的大写等价物是两个字符串"SS"。尽管如此,对于函数的稍微简单的定义,以及像 ISO 8859-1 (可能是最近使用最广泛的)这样的单字节编码, Upper2将做得相当好(假设'ß' 输入中没有),足够用于许多用途,而Upper1将可悲地失败。

于 2012-12-31T13:37:08.483 回答
2

如果您有来自英语 AZ 字母以外的其他语言的字母,例如日耳曼语 ä、ö 或 ü,以及法语/西班牙语中的各种重音字母,当然,如果输入是“germano”,则使用 toupper 将没有意义-latin” 语言,例如俄语。[正如 James 所指出的,这可能需要 Unicode 解析,这完全是一个全新的球赛,虽然']

显然,第一个函数也被硬编码以转换输入的前 27 个字符,这是不好的编码,因为函数不应该依赖字符串的大小 - 特别是因为 "std::string" 确实有长度第一!

于 2012-12-31T13:39:55.523 回答
0
  1. toupper()可以处理非ASCII字符
  2. 语法方面,Upper2()不易出错
  3. 对此不太确定,但我认为toupper()较慢
于 2012-12-31T13:23:47.867 回答