c++读字符值有时会得到不同的字母

C++ reading char values gives different letters sometimes

本文关键字:字符 c++      更新时间:2023-10-16

我必须写一个简短的例程,它将只写出颠倒顺序的大写字母。我设法编写了一些可以工作的代码,但是每当我用一个特定的输入测试我的代码时:

 7 ENTER a b C d E f G

代替G E C I get

 G (special) r E

我看不出是什么原因导致了这个问题,特别是因为它对很多其他情况都有效。下面是代码:

#include <iostream>
using namespace std;
int main() {  
int n;  
cin >> n;  
char stringa[n];  
int length = 0;  
for (int i = 0; i <= n-1; i++)  {
char letter;
cin >> letter;
 if (isupper (letter)) {
 stringa[((n-i) - 1)] = letter;
 length = length +1;
 }  }  for ( int i =0; i<=length-1; i++)  {
cout << ciag[i]

主要问题是您没有正确填充数组。

在填充数组之前没有初始化数组的内容,因此它包含随机垃圾。然后使用索引填充数组的特定元素,这些索引与每个大写字符在输入中的原始位置直接相关,而不是与它们在输出中应该出现的位置相关。

由于您没有初始化数组,并且输入大小写混合,因此您的数组将具有包含随机数据的间隙:

stringa[0]  = G
stringa[1]  = <random>
stringa[2]  = <random>
stringa[3]  = <random>
stringa[4]  = E
stringa[5]  = <random>
stringa[6]  = <random>
stringa[7]  = <random>
stringa[8]  = C
stringa[9]  = <random>
stringa[10] = <random>
stringa[11] = <random>
stringa[12] = <random>
stringa[13] = <random>
stringa[14] = R
stringa[15] = E 
stringa[16] = T
stringa[17] = N
stringa[18] = E
stringa[19] = <random>
stringa[20] = <random>

这就是您在乱码输出中看到的内容。

试试这样写:

#include <iostream>
#include <vector>
#include <cctype> 
int main()
{  
    int n;  
    std::cin >> n;  
    std::vector<char> stringa(n); // 'char stringa[n];' is not standard!
    int length = 0;  
    for (int i = 0; i < n; ++i)
    {
        char letter;
        std::cin >> letter;
        if (std::isupper (letter))
        {
            stringa[length] = letter;
            ++length;
        } 
    } 
    for (int i = length-1; i >= 0; --i)
    {
        std::cout << stringa[i];
    }
    return 0;
}

或:

#include <iostream>
#include <vector>
#include <algorithm>
#include <cctype>
int main()
{
    int n;  
    std::cin >> n;  
    std::vector<char> stringa(n); // 'char stringa[n];' is not standard!
    int length = 0;  
    for (int i = 0; i < n; ++i)
    {
        char letter;
        std::cin >> letter;
        if (std::isupper (letter))
        {
            stringa[length] = letter;
            ++length;
        } 
    } 
    std::reverse(stringa.begin(), stringa.begin()+length);
    for (int i = 0; i < length; ++i)
    {
        std::cout << stringa[i];
    }
    return 0;
}

两种方法都在第一个循环中生成以下数组内容,然后在第二个循环中简单地以相反的顺序输出:

stringa[0] = E
stringa[1] = N
stringa[2] = T
stringa[3] = E 
stringa[4] = R
stringa[5] = C
stringa[6] = E
stringa[7] = G

或者,我建议使用std::getline()代替读循环来获取用户的输入,然后根据需要简单地操作生成的std::string:

#include <iostream>
#include <string>
#include <algorithm>
bool IsNotUpper(char ch)
{
    return !std::isupper(ch);
}
int main()
{  
    std::string stringa;
    std::getline(std::cin, stringa); // returns "7 ENTER a b C d E f G"
    // so std::isupper() will return false for everything not in A-Z
    std::setlocale(LC_ALL, "C");
    stringa.erase(
        std::remove_if(stringa.begin(), stringa.end(), &IsNotUpper),
        stringa.end());
    // returns "ENTERCEG"
    std::reverse(stringa.begin(), stringa.end());
    // returns "GECRETNE"
    std::cout << stringa;
    return 0;
}

或者,如果使用c++ 11或更高版本,您可以使用lambda而不是std::remove_if()谓词的函数:

#include <iostream>
#include <string>
#include <algorithm>
int main()
{  
    std::string stringa;
    std::getline(std::cin, stringa);
    std::setlocale(LC_ALL, "C");
    stringa.erase(
        std::remove_if(
            stringa.begin(), stringa.end(),
            [](char ch){return !std::isupper(ch);}
        ),
        stringa.end());
    std::reverse(stringa.begin(), stringa.end());
    std::cout << stringa;
    return 0;
}

你的算法没有任何意义。您希望字符在数组中没有空格,但是当输入不是大写字母时,您跳过数组中的一个条目。相反,应该将大写字母放在数组中正向的连续槽中,然后以相反的顺序遍历。