【问题标题】:I can't find any error that will lead to this result我找不到任何会导致此结果的错误
【发布时间】:2021-10-11 16:05:12
【问题描述】:

我是 C++ 新手,想测试一下我实际学到了多少,所以我制作了这个简单的 cRaZyTeXt 生成器。但是有一个奇怪的错误我找不到任何解决方法。

代码在这里:

#include <iostream>
#include <string>
#include <algorithm>
#include <windows.h>

char convertToUppercase (char x)
{
    int asciiCode {static_cast<int>(x) - 32};
    char y {static_cast<char>(asciiCode)};

    return y;
}

char convertToLowercase (char x)
{
    int asciiCode {static_cast<int>(x) + 32};
    char y {static_cast<char>(asciiCode)};

    return y;
}

void toClipboard(const std::string &s){
    OpenClipboard(0);
    EmptyClipboard();
    HGLOBAL hg=GlobalAlloc(GMEM_MOVEABLE,s.size() + 1);
    if (!hg){
        CloseClipboard();
        return;
    }
    memcpy(GlobalLock(hg),s.c_str(),s.size() + 1);
    GlobalUnlock(hg);
    SetClipboardData(CF_TEXT,hg);
    CloseClipboard();
    GlobalFree(hg);
}

int main()
{
    std::cout << "Enter the text you want to convert into cRaZy TeXt: " << '\n';
    std::string userInput {};
    std::getline(std::cin >> std::ws, userInput);

    char userInputArray [userInput.size()];
    std::copy(userInput.begin(), userInput.end(), userInputArray);

    char outputArray [userInput.size()];

    for (int i = 0; i <= userInput.size(); ++i)
    {
        int x {static_cast<int>(userInputArray[i])};
        if (i % 2 == 0)
        {
            if (x <= 90 && x >= 65)
                outputArray[i] = convertToLowercase(userInputArray[i]);
            else
                outputArray[i] = userInputArray[i];
        }
        else
        {
            if (x <= 122 && x >= 97)
                outputArray[i] = convertToUppercase(userInputArray[i]);

            else
                outputArray[i] = userInputArray[i];
        }
    }
    std::cout << outputArray << '\n';
    toClipboard(outputArray);

    system("pause");
    return 0;
}

当我输入Hello, world! 时,它可以完全按照我想要的方式输出hElLo, WoRlD!proof

但是当我尝试my name is sean. 时,它的输出会是这样的:screenshot

mY NaMe iS SeAn.@y name is sean.@%�

更奇怪的是my name is ma sean.my name is sean ma. 都可以正常工作。

my name is ma sean.

my name is sean ma.

我在发布和调试配置中都尝试了以上四个输入,都一样。

请详细说明问题,让初学者的解释更友好。

感谢任何帮助。提前谢谢你。

【问题讨论】:

  • 如果我去掉剪贴板内容并在 Linux 下运行,则看不到此问题。
  • 正如其他人指出的那样,你不是 null 终止 outputArray 所以这可能是你的问题。试试char outputArray [userInput.size()] = {0};,它可以确保你的 c 字符串总是以 null 结尾。
  • 还有……你能做到吗?您不能像那样动态创建数组。使用std::string 否则你必须使用new 来创建一个动态大小的数组。
  • for (int i = 0; i &lt;= userInput.size(); ++i) 减一。尝试越界读写会导致未定义的行为。
  • 另外,char outputArray [userInput.size()]; 是非标准 C++。最好使用 std::stringpush_back 方法。

标签: c++ string algorithm uppercase lowercase


【解决方案1】:

对于初学者可变长度数组,例如该数组的声明

char userInputArray [userInput.size()];

不是标准的 C++ 功能。

不需要使用辅助数组来执行任务。您可以更改 std::string 类型的原始对象 userInput 本身。

这个变长数组

char outputArray [userInput.size()];

不包含用于终止零字符 '\0' 的空格,以使存储的字符序列成为字符串。

结果这个输出

std::cout << outputArray << '\n';

调用未定义的行为。

这个for循环

for (int i = 0; i <= userInput.size(); ++i)

导致访问超出声明的可变长度数组的内存,因为索引的有效范围是[ 0, userInput.size() )

此外,使用幻数(例如 65 或 90)也是一个坏主意。这会使代码不可读。

如果我理解正确的话,您需要的是如下演示程序中所示的函数。

#include <iostream>
#include <string>
#include <cctype>

std::string & cRaZyTeXt_generator( std::string &s )
{
    int upper_case = 1;

    for (auto &c : s)
    {
        if ( std::isalpha( static_cast< unsigned char >( c ) ) )
        {
            if ( ( upper_case ^= 1 ) )
            {
                c = std::toupper( static_cast< unsigned char >( c ) );
            }
            else
            {
                c = std::tolower( static_cast< unsigned char >( c ) );
            }
        }
    }

    return s;
}

int main()
{
    std::string s( "Hello, World!" );

    std::cout << s << '\n';
    std::cout << cRaZyTeXt_generator( s ) << '\n';
}

程序输出是

Hello, World!
hElLo, WoRlD!

【讨论】:

  • > 这个变长数组 char outputArray [userInput.size()];不包含用于终止零字符 '\0' 的空格,以使存储的字符序列成为字符串。你能详细说明一下吗?我阅读了一些教程,他们说 C++ 数组最后带有 '\0' 东西。那么我应该将其设为 char outputArray [userInput.size() + 1]; 吗?同样对于幻数,我想我可能至少应该在它旁边添加一条评论或使用 static_cast('a') 来获取它的 ASCII 码
  • @Seanmamasde 您正在自己填充数组。所以你至少需要使用 outputArray [userInput.size() + 1];并用终止零字符显式附加存储的字符序列。
猜你喜欢
  • 2011-06-22
  • 1970-01-01
  • 1970-01-01
  • 2014-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多