如何在从用户输入中读取多个数字时忽略 C++ 中整数数组中的空格

问题描述

我想反转数组,如果我给它一个没有任何空格的输入,代码可以正常工作,但如果其中有空格,它就不起作用。 例如我给出 1 2 3 4 而不是 1234,它会产生错误的答案。 我尝试使用从 int 到 string 的转换来使用 getline() 来摆脱空白,但这没有用。 这是我的代码

#include <iostream>
#include <string>
using namespace std;

int main()  
{  
string n,y;     // string var declared     
int z,rev=0,rem; // int var declared
getline(cin,n); // taken input as sting n
z = stoi(n); // converting sting n to int and storing in z
int *arr = new int(z); // setting z as dynamic array of integers
for (int x=0; x<=z; x++) { // running a loop till x <= z
    
        y = to_string(x); // converting integer x into a string y
        cin >> y;  // taking inputs as string y
        x = stoi(y); // converting string y to integer x
                // logic
        while(x!=0) { // while int x != 0 run loop
            
        rem=x%10;  // finding remainder
        rev=rev*10+rem; // adding remainder to var rev i.e reverse
        x/=10;    // rounding off to remaining numbers
        }       // closing loop of while
        cout<<rev; // printing the final reversed number
}               //closing for loop
return 0;  
}               //closing int main

解决方法

如果你只想处理数字,那么用这块去掉其他的一切:

getline(cin,n);
std::string inp;
for(auto &s : n)
if (std::isdigit(s)) inp.push_back(s);

然后使用inp,它将没有任何非数字字符。

如果要将这些数字作为独立的数字处理,可以这样做:

std::vector<int> num_inp;
for (auto &s : n) 
if (std::isdigit(s)) 
num_inp.push_back(std::stoi(s));

在 std::vector 中,每个数字都是它自己的数字。

,

可能的答案太多了,很难回答。您可以使用所有内置的 C++ 算法,或者您想要一个手工制作的解决方案。

这也取决于一点,如果您想验证输入并只允许数字和空格,或者您只想忽略空格。

在任何情况下,阅读带有 std::getline 的完整行,然后进行验证或忽略空格等都是首选的解决方案。

如果您已将输入读入 str,则可以使用 std::regex_match 对其进行验证。或者,您可以遍历字符串并逐个字符地检查字符。

忽略或消除空格可以通过 std::regex_replace 或通过将 std::string 放入 istringstream 并使用标准 io 函数从那里提取数字来完成。 使用格式化输入将跳过空格

这在直接从 std::cin 中读取时会出现问题,因为找到和线非常令人惊讶地非常困难。

看下面这个有点笨拙的例子:

#include <iostream>

int main() {

    unsigned long numberToReverse{};
    unsigned long numberTemp{};

    // Read as many number parts as existing,even devided by space
    while (std::cin >> numberTemp) {

        // We need to shift the previous read numbers to the left
        // This we do by multiplications of 10. For as many digits as we have in the new part
        unsigned long temp{ numberTemp };
        do {
            numberToReverse *= 10;
        } while (temp /= 10);
        // Now add the new digits to the right end
        numberToReverse += numberTemp;

        // In case of '\n',so 'end of line' stop
        if (std::cin.peek() == '\n') break;
    }
    // Reverse digits
    unsigned long outputNumber{};               // For output
    while(numberToReverse) {
        outputNumber *= 10;                     // Shift digits in output 1 position left
        outputNumber += numberToReverse % 10;   // Get next digit from input
        numberToReverse /= 10;                  // Look at next digit to the left of the input
    }
    // Show result
    std::cout << outputNumber << '\n';
    return 0;
}

好的,它确实只使用标准的 iosstream 设施,但它使用 peek 并且只有在输入末尾有一个数字直接后跟一个 '\n' 时才有效。所以,不是很好。

然后我们可以切换到首选解决方案并将完整行作为字符串读取。将该字符串放入 std::istringstream 并从中提取。

#include <iostream>
#include <string>
#include <sstream>

int main() {

    unsigned long numberToReverse{};

    // Read whateverinput to a string
    if (std::string inputAsString{}; std::getline(std::cin,inputAsString)) {

        // Put the string into a stringstream toextract the integers
        std::istringstream inputAsStringstream{ inputAsString };

        // Extract all numbers
        unsigned long numberTemp{};
        while (inputAsStringstream >> numberTemp) {

            // We need to shift the previous read numbers to the left
            // This we do by multiplications of 10. For as many digits as we have in the new part
            unsigned long temp{ numberTemp };
            do {
                numberToReverse *= 10;
            } while (temp /= 10);
            // Now add the new digits to the right end
            numberToReverse += numberTemp;
        }

    }
    // Reverse digits
    unsigned long outputNumber{};               // For output
    while (numberToReverse) {
        outputNumber *= 10;                     // Shift digits in output 1 position left
        outputNumber += numberToReverse % 10;   // Get next digit from input
        numberToReverse /= 10;                  // Look at next digit to the left of the input
    }
    // Show result
    std::cout << outputNumber << '\n';
    return 0;
}

请注意:不需要使用数组。您可以通过整数和模除法直接计算每个数字。为了确定正确的位置,我们可以将数字向左移动,乘以 10。

这些是标准方法,可能会在这里多次找到。

最后但并非最不重要的是,更现代的 C++ 解决方案,我们使用字符串。

#include <iostream>
#include <string>
#include <algorithm>
#include <iterator>

int main() {
    // Read string
    if (std::string inputAsString{}; std::getline(std::cin,inputAsString))
        // Show reversed output
        std::copy(inputAsString.crbegin(),inputAsString.crend(),std::ostream_iterator<char>(std::cout));
    return 0;
}

您当然可以在从 std::cin

读取字符串后使用一些验证机制 ,

我学习了向量来解决这个问题,希望这对将来可能遇到类似问题的人有所帮助。

#include <iostream>
#include <algorithm>
#include <vector>
  
using namespace std;

void display(vector<int> &v)
{
    reverse(v.begin(),v.end());
    
    for(int i=0; i < v.size(); i++)
    {
    cout<<v[i]<<" ";
}
}
int main()
{
    vector<int> n;
    int size,element;
    cout<<"enter the number of elements you want reversed ";
    cin>>size;
    for(int i=1; i<=size; ++i)
    {
        //cout<<"Enter elements to be reversed ";
        cin>>element;
        n.push_back(element);
    }
 
    display(n);
    return 0;
}
``