繁体   English   中英

奇怪的cout行为

[英]Weird cout behaviour

当使用std::cout向控制台输出内容时,我注意到了一个相当奇怪的行为。
我写了两个函数string& toUpper(std::string &str)string& toLower(std::string &str) ,它们应该完全按照以下方式调用:转换字符串全部大写或全部小写。

#include <string>
using namespace std;

string& toLower(string &str)
{
    for(char &c : str)
        c = tolower(c);

    return str;
}

string& toUpper(string &str)
{
    for(auto &c : str)
        c = toupper(c);

    return str;
}

现在我独立测试了这两个功能,它们按预期工作。 然后我在一个cout电话中链接了他们两个:

string str = "Hello World";
cout << toLower(str) << endl << toUpper(str) << endl;

我期待输出

hello world
HELLO WORLD

但我只是得到了

hello world
hello world

我使用printf进行了同样的测试,因为我认为这可能是cout做事的方式特有的但我得到了相同的结果,所以我猜我的代码出了点问题。
我的代码有什么问题?

您正在修改表达式求值中的变量(字符串),并且依赖于在评估期间的某些点使用它。 正如您所发现的那样,您不能依赖它。

一种解决方案是使用不同的字符串; 另一个是打破表达:

cout << toLower(str) << endl;
cout << toUpper(str) << endl;

它是c ++解析你的语句的方式:

cout << toLower(str) << endl << toUpper(str) << endl; //str = Hello World

第一步评估为上:

cout << toLower(str) << endl << str << endl;//str = HELLO WORLD

第二步评估到下:

cout << str << endl << str << endl;//str = hello world

第3步评估cout:

cout <<"hello world\nhello world\n";

你的cout产生这个结果的原因是因为它在打印之前修改了相同的字符串。 使用副本而不是引用来修复此问题。

operator<<的调用必须按顺序从左到右进行,但C ++标准没有指定语句中子表达式的求值顺序。

编译器可以决定评估子表达式的顺序,以便任何这些结果都是有效的:

auto&& arg1 = toLower(str);
auto&& arg2 = toUpper(str);
cout << arg1 << endl << arg2 << endl;

要么:

auto&& arg1 = toUpper(str);
auto&& arg2 = toLower(str);
cout << arg2 << endl << arg1 << endl;

要么:

auto&& arg1 = toUpper(str);
auto&& arg2 = (cout << arg1);
auto&& arg3 = toUpper(str);
arg2 << endl << arg3 << endl;

或其他几种可能性。 在这三种可能的顺序中,只有最后一种顺序会产生您期望的结果。 第一种情况会导致“HELLO WORLD”打印两次,第二种情况是您使用编译器得到的结果。 根据C ++标准,所有都是有效的结果。

问题是“何时调用函数”以及如何处理引用。 由于它是一个缓冲流,它似乎可能无序地调用它们。 如果删除返回的字符串的引用(因此,您为每个函数返回一个新的唯一字符串),代码将正常工作。

void toLower(string &str)
{
    for(char &c : str)
        c = tolower(c);

    return str;
}

void toUpper(string &str)
{
    for(auto &c : str)
        c = toupper(c);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM