0

Although there is few topics on scanf and line input reading, I was wondering on my code snippet why using it on a 2D array wasn't working is it an infinite loop even with the program ending correctly? Because it doesn't give an error nor it prints something on the output, if someone can enlighten me on what's wrong please?

using namespace std;

int main() {

    int t, j = 0;
    cin >> t;
    int arr2d[t][t];
    while (t--) {
        for (int i=0; i <= t; i++) {
            while (scanf("%d", &arr2d[i][j])) {
                cout << arr2d[i][j];
                j++;
            }
        }
    }
    return 0;
}

with the input being :

3
1 1 0
1 1 1
1 0 0

thank you!

Jay
  • 93
  • 5
  • `t` is not initialized, that's undefined behavior. – πάντα ῥεῖ Oct 28 '21 at 20:32
  • i'm sorry I've pasted the code incorrectly, It's as I have it now – Jay Oct 28 '21 at 20:33
  • Don't use a `while` loop. Use nested `for` loops: `for (int i = 0; i < t; i++) { for (int j = 0; j < t; j++) { cin >> arr2d[i][j]; }}` – 001 Oct 28 '21 at 20:36
  • Warning: No test was made, so you can't be certain that `t` received a good value. Crom only knows how big `arr2d` will be. Always check the stream state or return code after an IO transaction to ensure the transaction took place. Warning: Because `arr2d` is a variable length array (not legal in Standard C++) and `t` has not been restricted to safe bounds, a user can specify unsafe values, possibly as low as a few hundred, that will exhaust the program's Automatic storage. Chaos ensues when this happens. – user4581301 Oct 28 '21 at 20:49
  • thank you! didn't know scanf would accept line reading with a nested loop, I get now a little messy output but still get something though so I'll work with that thanks! :) – Jay Oct 28 '21 at 20:50
  • @user4581301 thanks for the answer! does that mean I should better allocate for the array? – Jay Oct 28 '21 at 20:51
  • Apologies. I totally neglected that part of the comment. You want to use a [`std::vector`](https://en.cppreference.com/w/cpp/container/vector), perhaps in [a wrapper like this](https://stackoverflow.com/a/2076668/4581301) to make it look 2D. – user4581301 Oct 28 '21 at 20:58
  • 1
    Don't mix the streams. Either use C language I/O, `scanf` and `printf` **or** use C++ I/O, `std::cin` and `std::cout`. – Thomas Matthews Oct 28 '21 at 21:06
  • Variable Length Arrays (VLAs) are not a part of standard C++. Array sizes must be constant expressions. Try using `std::vector` or dynamically allocating the memory at runtime. – Thomas Matthews Oct 28 '21 at 21:08
  • Your other option is to read each line into `std::string` and initialize a `std::stringstream` with the line and then extract the values from the stringstream. This can help when you don't know the exact number of values need to be read. In your case, looping is fine. – David C. Rankin Oct 28 '21 at 21:28
  • thanks to all of you for your answers! I've learned a lot with all your tips :) – Jay Oct 29 '21 at 07:56

1 Answers1

2

Here is one method for reading in a matrix:

unsigned int capacity = 0u;
std::cin >> capacity;
std::vector<int> matrix(capacity * capacity);
for (int row = 0; row < capacity; ++row)
{
    for (int column = 0; column < capacity; ++column)
    {
        int number;
        std::cin >> number;
        matrix[row * capacity + column] = number;
    }
    std::cin.ignore(10000, '\n'); // Reset to next line.
}
Thomas Matthews
  • 56,849
  • 17
  • 98
  • 154