我刚刚被介绍给toupper,我对语法有点困惑;好像它正在重演。我一直在使用的是字符串的每个字符,如果可能的话,它会将字符转换为大写字符。
for (int i = 0; i < string.length(); i++)
{
if (isalpha(string[i]))
{
if (islower(string[i]))
{
string[i] = toupper(string[i]);
}
}
}
为什么必须两次列出string[i]
?这不应该工作吗?
toupper(string[i]);
(我试过了,所以我知道它没有。)
答案 0 :(得分:4)
toupper
是一个按值获取其参数的函数。它可以被定义为对字符进行引用并就地修改它,但这会使编写仅检查字符的大写变体的代码变得更加尴尬,如这个例子:
// compare chars case-insensitively without modifying anything
if (std::toupper(*s1++) == std::toupper(*s2++))
...
换句话说,由于toupper(c)
没有改变c
的相同原因,sin(x)
不会更改x
。
string[i]
之类的表达式,请将引用添加到字符并使用它来读取和写入字符串:
for (size_t i = 0; i < string.length(); i++) {
char& c = string[i]; // reference to character inside string
c = std::toupper(c);
}
使用基于范围的for
,可以更简单地编写上述内容(并更有效地执行):
for (auto& c: string)
c = std::toupper(c);
答案 1 :(得分:2)
从documentation开始,字符按值传递 因此,答案是不,它不应该。
toupper
的原型是:
int toupper( int ch );
如您所见,字符按值传递,转换并按值返回 如果你没有将返回的值赋给变量,它肯定会丢失 这就是为什么在你的例子中它被重新分配,以便替换原来的。
答案 2 :(得分:1)
正如许多其他答案已经说过的那样,std::toupper
的参数被传递,结果返回 by-value ,这是有道理的,否则,你将无法做到打电话,说std::toupper('a')
。您无法就地修改文字'a'
。您也可能将输入放在只读缓冲区中,并希望将大写输出存储在另一个缓冲区中。所以按价值方法更灵活。
多余,另一方面,您需要检查isalpha
和islower
。如果该字符不是小写字母字符,toupper
无论如何都会不管它,所以逻辑会减少到这一点。
#include <cctype>
#include <iostream>
int
main()
{
char text[] = "Please send me 400 $ worth of dark chocolate by Wednesday!";
for (auto s = text; *s != '\0'; ++s)
*s = std::toupper(*s);
std::cout << text << '\n';
}
如果您觉得这个更漂亮,可以使用algorithm进一步消除原始循环。
#include <algorithm>
#include <cctype>
#include <iostream>
#include <utility>
int
main()
{
char text[] = "Please send me 400 $ worth of dark chocolate by Wednesday!";
std::transform(std::cbegin(text), std::cend(text), std::begin(text),
[](auto c){ return std::toupper(c); });
std::cout << text << '\n';
}
答案 3 :(得分:0)
toupper
按int
取值,并返回该大写字符的int
的{{1}}值。每次函数不将指针或引用作为参数时,参数将通过值传递,这意味着没有可能的方法来查看函数外部的更改,因为参数实际上是传递的变量的副本对函数来说,捕获更改的方法是保存函数返回的内容。在这种情况下,字符大写。
答案 4 :(得分:0)
请注意,isalpha()中有一个令人讨厌的问题,如下所示:函数 only 对0-255 + EOF范围内的输入正常工作。
那么,你认为。
好吧,如果你的char类型碰巧被签名,并且你传递的值大于127,那么这被认为是负值,因此传递给isalpha的int也将是负数(因此超出0-的范围) 255 + EOF)。
在Visual Studio中,这会使您的应用程序崩溃。我向微软抱怨过这个问题,理由是对所有输入都不安全的字符分类功能基本没有意义,但是得到的答案表明这完全符合标准,我应该编写更好的代码。好吧,公平,但标准中其他地方并不关心char是签名还是未签名。只有在isxxx功能中,它才能成为一种可以轻松通过测试而无需任何人注意的地雷。
以下代码崩溃Visual Studio 2015(据我所知,所有早期版本):
int x = toupper ('é');
因此,不仅代码中的isalpha()是多余的,它实际上是有害的,因为它会导致包含值大于127的字符的任何字符串使应用程序崩溃。
参见http://en.cppreference.com/w/cpp/string/byte/isalpha:“如果ch的值不能表示为unsigned char且不等于EOF,则行为未定义。”