-1

There is an array of integers, and I want to turn them into an array of separated digits and print them back out as the same sets of integers.

ps: reason being, I want to do lots of individual digit calculations, and I want to use this method to separate the digits, and store their "separating indexes" to turn them back to different integers afterward.

However, there is a problem, almost all the digits are translated correctly but some of them at each individual ends are wrong.

CODE:

#include <iostream>

using std::cout; using std::endl;

int* charArrToIntArray(char** input, int* sizeofnumbers, int sizeofarray) {
    int* output = new int[100];
    cout << input[0][0] << endl;
    cout << sizeofnumbers[0] << endl;
    cout << sizeofarray << endl;
    for (int counter = 0; counter < sizeofarray; counter++) {
        int i;
        sscanf_s(input[counter], "%d", &i);
        output[counter] = i;
    }
    return output;
}

int* intToIntArray(int input, int length) {
    static int output[20];
    for (int i = 0; i < length; i++) {
        output[i] = input % 10;
        input /= 10;
    }
    return output;
}

int main()
{
    const int arraySize = 5;
    int NumSize[arraySize] = { 6, 7, 5, 9, 8 };
    int NumSizeFlatten[arraySize + 1] = { 0 };
    static int IntArray[arraySize] = {345678, 6543210, 11101, 110010001, 00011100};
    static int arr2D[500]; //The flat 2D array...
    for (int counter = 0; counter < arraySize; counter++) {
        int* arr1D = intToIntArray(IntArray[counter], NumSize[counter]);

        for (int i = 0; i <= counter; i++) {
            NumSizeFlatten[counter + 1] += NumSize[i]; //Get the values of positions of flattened array's separation points
        }

        for (int i = NumSize[counter] - 1; i >= 0; i--) {
            printf("%d", arr1D[i]); //Directly Print from the arrays
        }printf("\n");

        for (int i = 0; i < NumSize[counter]; i++) {
            arr2D[NumSizeFlatten[counter] + i - 1] = arr1D[NumSize[counter] - i]; //PUT arrays into a Flattened array //warning C6386: buffer overrun
        }
    }

    for (int i = 0; i < 50; i++) {
        printf("%d", arr2D[i]); //Directly print the Flattened array in a flattened from.
    }

    for (int j = 1; j <= arraySize; j++) {
        printf("NumSizeFlatten[%d] = %d\n", j, NumSizeFlatten[j]); //Print the values of positions of flattened array's separation points
    }

    for (int i = 0; i < arraySize; i++) {
        for (int j = NumSizeFlatten[i]; j < NumSizeFlatten[i + 1]; j++) {
            //printf("%d.", j);
            printf("%d", arr2D[j]); //Print From the Flattened Array
        }printf("\n");
    }
}

OUTPUT:

345678
6543210
11101
110010001
00004672
34567065432151110011001000100004670000000000000000NumSizeFlatten[1] = 6
NumSizeFlatten[2] = 13
NumSizeFlatten[3] = 18
NumSizeFlatten[4] = 27
NumSizeFlatten[5] = 35
345670
6543215
11100
110010001
00004670

and also the last integer is wrong.

I know this code is really trash, I am doing what I can...

Tommy Lau
  • 25
  • 6
  • `int* output = new int[100];` -- Maybe off-topic, but your code leaks memory. Use `std::vector` and `std::vector` in general. – PaulMcKenzie Feb 21 '22 at 17:52
  • [What is a debugger, and how can it help diagnose problems?](https://stackoverflow.com/questions/25385173/what-is-a-debugger-and-how-can-it-help-me-diagnose-problems) – PaulMcKenzie Feb 21 '22 at 17:58
  • Also, why are you trying 5 numbers when clearly the first number is wrong? If you focus on the first wrong value and attempt to fix that, then maybe the others will work also. – PaulMcKenzie Feb 21 '22 at 18:05
  • `00011100` -- Also, this is an octal constant, not a decimal constant. If the integer starts with 0, it is considered octal. That's why the last value seems to be far off. The octal value of 00011100 in decimal is 4672, not too far away from your output of 4670. Still, the last digit is off, which explains the difference of 2. – PaulMcKenzie Feb 21 '22 at 18:37
  • 2
    Advice -- what you are trying to accomplish is much easier using `std::vector`. Not only easier, but safer due to not having to use `new[]`, thus won't have the issue of memory leaks. The issue with your current code is basically you are generating reversed numbers in `intToIntArray`. The easiest thing for you to do *with your current code* is to create the array of digits as-is, not reversed. You need to fix `intToIntArray` to do this. Once you do that, then the rest of the code becomes much easier to handle (no backwards-running loops, etc.). – PaulMcKenzie Feb 21 '22 at 18:42

1 Answers1

1

Can you use the STL data structures and algorithms?

Here's some code:

  • Starting from a vector of ints.
  • Creating a vector of strings from it.
  • Flattening the vector of strings into a vector of int digits.
  • Transforming the vector of strings back into a vector of ints.

[Demo]

#include <algorithm>  // for_each, transform
#include <fmt/ranges.h>
#include <sstream>  // ostringstream
#include <string>  // to_string
#include <vector>

#include "range/v3/all.hpp"

int main()
{
    // Ints
    const std::vector<int> vi{345678, 6543210, 11101, 110010001, 00011100};
    fmt::print("vi = {}\n", vi);

    // Ints to strings
    std::vector<std::string> vs{};
    std::ranges::transform(vi, std::back_inserter(vs), [](int i) {
        return std::to_string(i);
    });
    fmt::print("vs = {}\n", vs);

    // Strings to flat ints
    std::vector<int> flat_vi{};
    std::ranges::for_each(vs, [&flat_vi](const auto& s) {
        std::ranges::transform(s, std::back_inserter(flat_vi), [](unsigned char c){
            return c - '0';
        });
    });
    fmt::print("flat_vi = {}\n", flat_vi);

    // Strings to flat ints (using ranges)
    auto flat_vi_2 = vs
        | ranges::view::join
        | ranges::view::transform([](unsigned char c) { return c - '0'; })
        | ranges::to_vector;
    fmt::print("flat_vi_2 = {}\n", flat_vi_2);
    
    // Strings back to ints
    std::vector<int> vo{};
    std::ranges::transform(vs, std::back_inserter(vo), [](const auto& s){
        return std::atoi(s.c_str());
    });
    fmt::print("vo = {}\n", vo);
}

// Outputs:
//
//   vi = [345678, 6543210, 11101, 110010001, 4672]
//   vs = ["345678", "6543210", "11101", "110010001", "4672"]
//   flat_vi = [3, 4, 5, 6, 7, 8, 6, 5, 4, 3, 2, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 4, 6, 7, 2]
//   flat_vi_2 = [3, 4, 5, 6, 7, 8, 6, 5, 4, 3, 2, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 4, 6, 7, 2]
//   vo = [345678, 6543210, 11101, 110010001, 4672]

Updating my answer after your comment.

  • You may still be able to do most of your work on data structures like std::vector and then, pass an array of int digits around.
  • This is quite a not recommended practice because you have to take care you don't modify the std::vector while other code is operating on its data. Otherwise, you would get undefined behaviour (basically, the modification may cause a relocation of the contents, so the pointer to those contents would no longer be valid).
  • Also, if you think of executing code in parallel, notice many of the STL algorithms already offer that capability. E.g. check std::transform's overloads using an ExecutionPolicy.

[Demo]

#include <span>

void operate_on_flat_vector_data(int* data, size_t size)
{
    std::cout << "flat_vi.data() = [";
    bool first{true};
    for (size_t i{0}; i < size; ++i) {
        std::cout << (first ? "" : ", ") << data[i];
        first = false;
    }
    std::cout << "]\n";
}

void operate_on_flat_vector_data(std::span<const int> data)
{
    std::cout << "flat_vi.data() = [";
    bool first{true};
    for (const int i : data) {
        std::cout << (first ? "" : ", ") << i;
        first = false;
    }
    std::cout << "]\n";
}

int main()
{
    // Passing flat vector's data around
    operate_on_flat_vector_data(flat_vi.data(), flat_vi.size());

    // Passing flat vector's data around (using span)
    operate_on_flat_vector_data({flat_vi.data(), flat_vi.size()});
}
rturrado
  • 7,699
  • 6
  • 42
  • 62
  • 1
    I don't want to use STL vector because I want to transfer the array to elsewhere without turning it back into arrays, but your example is good tho. Yeah, if I can use vector it's easier to do so. I found some fun equations and thinking that maybe it's way quicker when I use my GPU to brute force it, so I want to separate the digits and put individual digits into each thread to calculate them, that's why I don't want to use vector. – Tommy Lau Feb 22 '22 at 00:52
  • 1
    Thanks, There are lots of STL functionalities that I've never used before, I will take a look, thanks! – Tommy Lau Feb 23 '22 at 17:55