0

Starting out C++ in my school and it is looking so much more daunting than Python! Hopefully someone can guide me on this.

I have created a simple user I/O to practice on extracting integer from the user input and forming an array based on the inputs. See below:

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

When entering the input, the user need to adhere to this format

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

I have this in my mind which I believe will work but I can't translate it into C++.

  1. Program will extract the first and last integer from user input, '-' will be remove. I am thinking that regex can do the trick but not too sure how to code it in.
  2. Based on the first and last integer, it will form an integer array in number_array. For example, 0-5 will form [0, 1, 2, 3, 4, 5] and -4--1 will form [-4, -3, -2, -1]. I assume a for loop will need to be use here.
5
  • Are the numbers limited to one digit? Asking because one of the answers below requires the numbers to be one digit. Commented Jul 4, 2020 at 15:18
  • for #1, you don't need a regex (although you could use it for input verification) -- you can just write a helper method to sanitize the input; for #2, you can use a for loop or boost::irange with a C-style array or std::array. Commented Jul 4, 2020 at 15:20
  • It can be more than one digit such as 15-25. Commented Jul 4, 2020 at 15:20
  • @user3118602 why are you speaking about digit in your question if 15-25 allowed ? what is the expected result for 15-25 : [1, 2 ... 5] or [15, 16, ... 25] ? please be clear when you write a question ... Commented Jul 4, 2020 at 15:33
  • @bruno Edited the English to make it super clear. :) Commented Jul 4, 2020 at 15:41

3 Answers 3

2

cin >> string will stop at whitespace, so let's use std::getline which will grab a whole line of input.

And regexs are certainly a way of doing this:

code

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

output

> 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

that being said

Since you're parsing something pretty simple, you could also just use:

fscanf("%d - %d", &start, &end) and ignore the regex idea all together.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, I seems to understand how you approached this but there is something missing. The numbers are suppose to be added into the empty array called number_array. I am currently searching online and seems like the approach to appending the number to my empty array is to use vector.
0

For the 'parsing' you can do something like :

char c1,c2,minus;

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

it is useless to do more complicated while the numbers are just a digit

For the array in the 'ok case' you can do

std::vector<int> number_array;

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

Example :

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

Compilation and executions:

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:~ $ 

After your edit

Finally reading 2 integers rather than just 2 digits, to use scanf as proposed by the other answer is probably the simpler solution :

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

Compilation and execution:

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:~ $

Comments

0

Here's a simple way to do what you want.

First read the input:

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

Then generate the range that you want:

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

Here's a demo.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.