【问题标题】:Extract integer from string and form an array从字符串中提取整数并形成一个数组
【发布时间】:2020-10-25 01:51:42
【问题描述】:

在我的学校开始使用 C++,它看起来比 Python 更令人生畏!希望有人可以指导我。

我创建了一个简单的用户 I/O 来练习从用户输入中提取整数并根据输入形成一个数组。见下文:

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

int main() {

    int number_array = {};
    string user_input;

    cout << "Enter your array range: ";
    cin >> user_input;
    cout << "You have entered: " + user_input << endl;

    return 0;
}

用户在输入时需要遵守这种格式

x-y or x - y (e.g 0-5 or 0 - 5)

我有这个想法,我相信它会起作用,但我无法将它翻译成 C++。

  1. 程序将从用户输入中提取第一个和最后一个整数,“-”将被删除。我认为正则表达式可以解决问题,但不太确定如何编写代码。
  2. 根据第一个和最后一个整数,在number_array中形成一个整数数组。例如,0-5 将形成 [0, 1, 2, 3, 4, 5],-4--1 将形成 [-4, -3, -2, -1]。我假设这里需要使用 for 循环

【问题讨论】:

  • 数字是否限制为一位?询问是因为以下答案之一要求数字为一位数。
  • 对于#1,您不需要正则表达式(尽管您可以将其用于输入验证)——您只需编写一个辅助方法来清理输入;对于 #2,您可以使用 for 循环或 boost::irange 与 C 样式数组或 std::array
  • 可以多于一位,比如15-25。
  • @user3118602 如果允许 15-25,您为什么要在问题中谈论数字? 15-25 的预期结果是什么: [1, 2 ... 5] 或 [15, 16, ... 25] ?写问题时请清楚...
  • @bruno 编辑了英文以使其超级清晰。 :)

标签: c++ arrays string c++11


【解决方案1】:

cin &gt;&gt; string 将在空白处停止,所以让我们使用 std::getline 来获取整行输入。

而正则表达式当然是这样做的一种方式:

代码

#include <iostream>
#include <cstring>
#include <regex>

int main() {

    int number_array = {};
    std::string user_input;

    std::cout << "Enter your array range: ";
    std::getline(std::cin, user_input);
    std::cout << "You have entered: " + user_input << "\n";

    std::smatch m;
    std::regex r(R"(^(\d+) *- *(\d+)$)");
    if (!regex_match(user_input, m, r)) {
      std::cout << "Didn't match regex!\n";
      return 1;
    }

    int start = std::stoi(m[1]);
    int end = std::stoi(m[2]);

    for (int i=start; i<=end; i++) {
      std::cout << i << " ";
    }
    std::cout << "\n";

    return 0;
}

输出

> clang++-7 -pthread -std=c++17 -o main main.c
pp
> ./main
Enter your array range: 1 -- 4
You have entered: 1 -- 4
Didn't match regex!
exit status 1
> ./main
Enter your array range: 4 -  10
You have entered: 4 -  10
4 5 6 7 8 9 10 

https://repl.it/repls/FunctionalGiantChapters

据说

由于您解析的内容非常简单,因此您也可以使用:

fscanf("%d - %d", &amp;start, &amp;end) 并忽略正则表达式的想法。

【讨论】:

  • 谢谢,我似乎理解您是如何处理这个问题的,但缺少一些东西。假设将这些数字添加到名为 number_array 的空数组中。我目前正在网上搜索,似乎将数字附加到我的空数组的方法是使用向量。
【解决方案2】:

对于“解析”,您可以执行以下操作:

char c1,c2,minus;

if ((cin >> c1 >> minus >> c2) && (minus == '-') &&
    isdigit(c1) && isdigit(c2))
  ...ok case...
else
  ...nok case...

数字只是一个数字,再复杂也没有用

对于'ok case'中的数组,你可以这样做

std::vector<int> number_array;

for (int i = c1; i <= c2; ++i)
  number_array.push_back(i - '0');

例子:

#include <iostream>
#include <vector>
#include <ctype.h>

int main()
{
  char c1,c2,minus;

  if ((std::cin >> c1 >> minus >> c2) && (minus == '-') &&
      isdigit(c1) && isdigit(c2)) {
    std::vector<int> number_array;
    
    for (int i = c1; i <= c2; ++i)
      number_array.push_back(i - '0');
    
    // check
    for (auto v: number_array)
      std::cout << v << ' ';
    std::cout << std::endl;
  }
  else
    std::cerr << "invalid input" << std::endl;
}

编译和执行:

pi@raspberrypi:~ $ g++ -Wall c.cc
pi@raspberrypi:~ $ ./a.out
0-5
0 1 2 3 4 5 
pi@raspberrypi:~ $ ./a.out
0 - 5
0 1 2 3 4 5 
pi@raspberrypi:~ $ ./a.out
0- 5
0 1 2 3 4 5 
pi@raspberrypi:~ $ ./a.out
0 -5
0 1 2 3 4 5 
pi@raspberrypi:~ $ 

修改后

最后读取 2 个整数而不是 2 个数字,使用 scanf 作为另一个答案的建议可能是更简单的解决方案:

#include <iostream>
#include <vector>

int main()
{
  int v1, v2;
  
  if (scanf("%d - %d", &v1, &v2) == 2) {
    std::vector<int> number_array;
    
    while (v1 <= v2)
      number_array.push_back(v1++);
    
    // check
    for (auto v: number_array)
      std::cout << v << ' ';
    std::cout << std::endl;
  }
  else
    std::cerr << "invalid input" << std::endl;
}

编译和执行:

pi@raspberrypi:~ $ g++ -Wall c.cc
pi@raspberrypi:~ $ ./a.out
0-5
0 1 2 3 4 5 
pi@raspberrypi:~ $ ./a.out
0 -5
0 1 2 3 4 5 
pi@raspberrypi:~ $ ./a.out
0 - 5
0 1 2 3 4 5 
pi@raspberrypi:~ $ ./a.out
0- 5
0 1 2 3 4 5 
pi@raspberrypi:~ $

【讨论】:

    【解决方案3】:

    这里有一个简单的方法来做你想做的事。

    首先读取输入:

    int low, high;
    char dash; 
    std::cin >> low >> dash >> high;
    

    然后生成你想要的范围:

    std::vector<int> v(high - low + 1);
    std::iota(v.begin(), v.end(), low);
    

    这是demo

    【讨论】:

      猜你喜欢
      • 2011-01-22
      • 2019-03-09
      • 1970-01-01
      • 1970-01-01
      • 2013-03-09
      • 2020-07-20
      相关资源
      最近更新 更多