1

I know there are similar questions on Stack overflow about this. I already checked them. Here are two points:

  1. The number will be an input from the user, so I won't know how many digits the number may actually contain

  2. I DON'T want to directly print the digits, I need to do some further process on every digit, so I need a way to save or assign every single digit. So fore example, if the user enters 1027, I'll need 1, 0, 2, 7 returned, and not printed. That's where my problem starts. Here's how I'd write it if it could be printed:

int x;
cin>>x;
while(x != 0)
{
   cout<<x%10<<endl;
   x/=10;
}

Any hints or help is in advance appreciated.

underscore_d
  • 6,309
  • 3
  • 38
  • 64
Liana
  • 314
  • 5
  • 15
  • 2
    So you want those digits *stored* somewhere, in a *container* of some kind. Are you familiar with containers? – Beta Jun 29 '20 at 14:40
  • You want to store each of the digit (whereas the number of digits are unknown)? – Rohan Bari Jun 29 '20 at 14:40
  • 2
    `std::string s; std::cin >> s;` ?(possibly check input). – Jarod42 Jun 29 '20 at 14:43
  • @Beta yes, I want them stored. I'm not sure what you mean about a container, what I thought of doing was storing them in an array, which sounds like an effort. I – Liana Jun 30 '20 at 05:32
  • @RohanBari No, I need to know what the numbers are as well. – Liana Jun 30 '20 at 05:33

4 Answers4

4

It depends what order you need it in. If you need least-significant digit (rightmost) to most-significant (leftmost), then your solution is almost there

int x = ...
while(x != 0)
{
   int current = x % 10; // get rightmost digit
   x /= 10;
   // process 'current', or store in a container for later processing
}

If you need most-significant (leftmost) to least-significant (rightmost), then you can do this recursively:

void for_each_digit(int input)
{
  // recursive base case
  if (input == 0) { return; };    

  int current = input % 10
  for_each_digit(input / 10); // recurse *first*, then process
  // process 'current', add to container, etc
}

// ...


int x = ...
for_each_digit(x);

Edit: I apparently missed the part about returning a sequence of digits.

Either approach works. If you go right-to-left, you will need to reverse the container first. If you go recursive, you will need to append each value to the container.

Human-Compiler
  • 11,022
  • 1
  • 32
  • 59
2

Use a std::string:

std::string input;
std::cin >> input;

Now input[i] is the i-th digit. input.size() is the number of digits.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
  • 1
    If this were an interview question, this answer would not pass the interview. As such, it's not a particularly good recommendation since it does not demonstrate knowledge of the algorithm required to come to a good solution – Human-Compiler Jun 29 '20 at 14:44
  • 1
    @Human-Compiler then I dont want the job – 463035818_is_not_an_ai Jun 29 '20 at 14:45
  • 2
    @Human-Compiler seriously, If they want me to show of my knowledge about the algorithm they should tell me. If they ask me to provide a way to get digits from a number entered by user, then this is it. There was no mention of interview in the question btw. Anyhow, I'd be happy to find out in the interview that we dont make a match and not only later – 463035818_is_not_an_ai Jun 29 '20 at 14:49
  • 1
    Yikes, my comment wasn't meant to instigate anything. This sounds like either a homework or interview-style question, which is why I mentioned it. The original post mentioned processing each digit -- which if they are chars from a `std::string` requires an additional level of changes (e.g. `c - '0'` as opposed to operating on each `int`). This is often an entry-level "fizzbuzz"-style interview question. – Human-Compiler Jun 29 '20 at 14:53
  • @Human-Compiler Well, that could easily be a transformation from a `std::string` to a `std:vector`. So you could demonstrate in the supposed interview that you know about containers *and* algorithms ;). – Bob__ Jun 29 '20 at 15:00
  • @Human-Compiler no worries. Your point of view is completely valid. Making tutors or interviewers happy can be important. I just thought OP should get both: The longwinded and the easy-cheaty ;) – 463035818_is_not_an_ai Jun 29 '20 at 15:01
  • IMHO, this is more efficient because it doesn't use division. Processors really hate division. – Thomas Matthews Jun 29 '20 at 15:27
  • @idclev463035818 Since I should ask the user the number of the test cases in the beginning of the program, I will need several times of inputting several numbers, which each number will have to be split in the digits and face some process. Wouldn't this be a little bit complicated this way? – Liana Jun 30 '20 at 05:37
  • @Liana I dont understand why you think it would be compilcated. What you can do with one string you can also do with `n` strings – 463035818_is_not_an_ai Jun 30 '20 at 06:21
1

Well you can use vector. It can take variable length input. You need not declare the size beforehand. Learn more about vector here: vector

#include<iostream>
#include<vector>
#include <algorithm> // std::reverse
using namespace std;

int main(void)
{
    vector<int>digits;
    int x;
    cin >> x;

    while(x)
    {
        digits.push_back(x % 10);
        x = x / 10;
    }

    // reversing the order of the elements inside vector "digits" as they are collected from last to first and we want them from first to last.
    reverse(digits.begin(), digits.end());
    
    // Now the vector "digits" contains the digits of the given number. You can access the elements of a vector using their indices in the same way you access the elements of an array.
    for(int i = 0; i < digits.size(); i++) cout << digits[i] << " ";

    return 0;
}
hafiz031
  • 2,236
  • 3
  • 26
  • 48
  • 2
    A little edit would make it better. Rather than storing the vector globally, change the visibility scope to local by putting it into the main function. And don't forget to define `(void)` and return 0 explicitly. – Rohan Bari Jun 29 '20 at 15:01
  • @RohanBari `(void)` is unnecessary and pointless in C++. Also, `main()` gets an implicit `return 0;` if we omit that, although I prefer to write it explicitly anyway. – underscore_d Jun 29 '20 at 15:21
0

You may try std::vector<int> to store unknown number of integers as shown:

#include <iostream>
#include <vector>

int main(void) {
    std::vector<int> digits;
    std::string s;

    std::cout << "Enter the number: ";
    std::cin >> s;

    size_t len = s.length();

    for (size_t i = 0; i < len; i++) {
        digits.push_back(s[i] - '0');
    }
    
    // Comment next 3 code to stop getting output
    for (size_t i = 0; i < len; i++)
        std::cout << digits[i] << ' ';
    std::cout << std::endl;

    return 0;
}

Note: This approach doesn't performs any mathematical operations (i.e. operation of division and getting remainders). It simply stores each integer in a vector using a for loop.

Rohan Bari
  • 7,482
  • 3
  • 14
  • 34
  • Why do you bother copying into a new raw array of char and then reading that? `std::string` has `.begin()`/`.end()` (and hence works with range-`for`), `operator[]`, `.data()`, etc. It is not good to recommend use of `new`. End users should almost never have to write `new` or `delete`. Also, in this case, it's supremely unnecessary. – underscore_d Jun 29 '20 at 15:22
  • @underscore_d You're quite right. Answer updated. – Rohan Bari Jun 29 '20 at 15:25