C ++读取char值有时会给出不同的字母

时间:2015-10-27 00:28:03

标签: c++

我必须编写一个简短的例程,它只会按相反的顺序写出大写字母。我设法收集了某种程度上可行的代码,但每当我用一个特定的输入测试我的代码时:

 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]

2 个答案:

答案 0 :(得分:1)

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

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

由于您没有初始化数组,并且输入混合了下/上外壳,因此您的数组将包含包含随机数据的间隙:

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;
}

答案 1 :(得分:0)

你的算法没有任何意义。您希望字符在数组中没有间隙,但是当输入不是大写字母时,您跳过数组中的条目。相反,将大写字母放在数组中的前向插槽中,然后以相反的顺序遍历它。