簡體   English   中英

C++ 讀取字符值有時會給出不同的字母

[英]C++ reading char values gives different letters sometimes

我必須編寫一個簡短的例程,它只會以相反的順序寫出大寫字母。 我設法收集了以某種方式起作用的代碼,但是每當我使用一個特定輸入測試我的代碼時:

 7 ENTER a b C d E f G

而不是讓GECI 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;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM