此数组转换如何工作(使用字符串从小写到大写)

How does this array conversion work ( lowercase to uppercase using a string)?

本文关键字:字符串 数组 转换 何工作 工作      更新时间:2023-10-16

我让程序按预期工作,但谁能解释一下它是如何工作的?

#include <iostream>
using namespace std;
int main(void) {
    int exit;     
    string name;
    cin >> name;
    for (int i = 0; i < name.length(); i++) {
        // the line below is the one I don't understand 
        if ('a' <= name[i] && name[i] <= 'z') name[i] = char(((int)name[i]) - 32);
    }
    cout << name;
    cin >> exit;
    return 0;
 }

编辑:让我改写一下:

我不明白的是字符串到数组交易是如何工作的,例如: 'a'<= name[i] .这究竟比较什么,如何比较?

编辑2感谢您的快速回复,伙计们,爱你们所有人。我想通了。

这是一行:

 if('a'<=name[i] && name[i]<='z')name[i]=char(((int)name[i])-32);

细分:

 if( 'a'<=name[i] ) {
   if( name[i]<='z' ) {
     // name_int is a temporary, which the above code implicitly creates,
     // but doesn't give a name to:
     int name_int = name[i];
     name_int = name_int - 32;
     name[i] = char(name_int);
   }
 }

请注意,32恰好与您正在使用的字符编码中的'a'-'A'相等。

(从技术上讲,name_int应该是一个int&&或类似的东西,但没有必要那么混乱。

我从您评论中的编辑中假设您想知道[]如何应用于string对象。运算符 [] 被重载,以便string返回对所表示字符串的指定位置偏移处的字符的引用。不需要将string直接转换为数组。实现重载的代码很可能是遍历链表。这取决于string的实施方式。

它采用 ASCII 字符格式,从小写转换为大写,从原始 ASCII 值中减去 32。这是因为大写的 ASCII 值小于小写的 ASCII 值,并且它是 AaBb 等之间的恒定差异。

供参考: http://www.asciitable.com/

'a' <= name[i] && name[i] <= 'z'

此行比较这两个字符的相应 ASCII 值。 ASCII 中的'a'为 97,'z'为 122。如果 name[i] 是从 'a''z' 个字符之一,则表达式返回 true。这通常用于检查变量是否按字母顺序排列。

if ('a' <= name[i] && name[i] <= 'z')

char对象是类似于整数的数值。因此,'a' <= name[i]只是测试'a'的数值是否小于或等于您正在检查的字符。结合name[i] <= 'z',您将测试name[i]的数值是否介于'a''z'之间的值之间。现在,碰巧的是,将数值分配给char s的最常见方案,称为"美国信息交换标准代码"(ASCII),字母表按顺序排列; 'a' + 1 = 'b''b' + 1 = 'c'等等。因此,弄清楚字符是否在 'a''z' 之间会告诉您它是否是小写字母。

name[i] = char(((int)name[i]) - 32);

一旦你知道char只是数值,你可以从我们在小学学到的算术的基本属性中推断出'a' + ('A' - 'a')导致值'A'。此外,ASCII 的大写字母表与小写字母表的排列方式相似,因此 'A' + 1 = 'B' , etc. So taking any char in the lower case alphabet and adding 'A' - 'a' will result in the upper case version of that letter. In ASCII 'A' - 'a'' 恰好具有值 -32。因此,取小写字母的数值,减去 32,您就有了大写字母的值。

为了进行比较,这里有一个不依赖于ASCII的代码版本:

auto l = std::locale();
if (std::islower(name[i], l))
    name[i] = std::tolower(name[i], l);