-1

In C++ it is possible to print all elements of an one-dimensional array like this :

char abc[3]={'a', 'b', 'c'};
cout<<abc<<endl;

My question is whether there is a way to do that with multidimensional arrays. Is it possible to print only one row of an array? I've tried this:

char abc[3][3]={
{'a', 'b', 'c'},

{'d', 'e', 'f'},

{'g', 'h', 'i'},

};

cout << abc[0] << endl;

However this code prints the entire array(from 'a' to 'i').

Of course I can use the "for" loop and simply iterate through the first row elements but I'm sure there should be a more compact way of doing it.

Any help would be appreciated.

BuderBrodas
  • 27
  • 1
  • 5
  • 3
    *In C++ it is possible to print all elements of an one-dimensional array like this : ...* No, this is UB because `abc` is not null-terminated. – Evg Jul 29 '20 at 09:35
  • 2
    `Of course I can use the "for" loop and simply iterate through the first row elements` that's the only sane way. – kesarling He-Him Jul 29 '20 at 09:36
  • 2
    Agreed with @d4rk4ng31. BuderBrodas it would be better to avoid doing hacks unless you really need it. I've posted an answer below please check. – Just Shadow Jul 29 '20 at 09:57

4 Answers4

2

Is it possible to print only one row of an array

You can, but each of the row should be self terminated with '\0' character.

So something like:

char abc[][4] = {
    {'a', 'b', 'c', '\0'},

    {'d', 'e', 'f', '\0'},

    {'g', 'h', 'i', '\0'},

};

cout << abc[1] << endl;  // print the second row

cout a non-terminated character array like your original code causes undefined behaviour.

artm
  • 17,291
  • 6
  • 38
  • 54
1

You can null terminate the rows:

char abc[][4] = { // notice 4
    {'a', 'b', 'c'},
    {'d', 'e', 'f'},
    {'g', 'h', 'i'},
};

std::cout << abc[1] << '\n';

Or use an explicit loop somewhere:

#include <cstdio>
#include <span>

char abc[][3] = {
    {'a', 'b', 'c'},
    {'d', 'e', 'f'},
    {'g', 'h', 'i'},
};

void print_row(std::span<char> sp) {
  for (auto const ch : sp) {
    std::putchar(ch);
  }
}

int main() { 
    print_row(abc[1]); 
}
Aykhan Hagverdili
  • 28,141
  • 6
  • 41
  • 93
  • If I understood correctly you're code has the same meaning as "artm" with the difference that in the artm's code null terminating is done manually, correct? – BuderBrodas Jul 29 '20 at 09:53
0

C++11, C++14

std::cout << "First case:" << std::endl;
std::cout << std::string(std::begin(abc[0]), std::end(abc[sizeof(abc) / sizeof(abc[0]) - 1])) << std::endl;

std::cout << "Second case:" << std::endl;
std::for_each(std::begin(abc), std::end(abc), [](const auto& v) { std::cout << std::string(std::begin(v), std::end(v)) << std::endl; });

C++17: use std::string_view without temporary std::string object

std::cout << "First case:" << std::endl;
std::cout << std::string_view(std::begin(abc[0]), std::end(abc[sizeof(abc) / sizeof(abc[0]) - 1])) << std::endl;

std::cout << "Second case:" << std::endl;
std::for_each(std::begin(abc), std::end(abc), [](const auto& v) { std::cout << std::string_view(std::begin(v), std::end(v)) << std::endl; });

Output:

First case:
abcdefghi
Second case:
abc
def
ghi
Amir Kadyrov
  • 1,253
  • 4
  • 9
  • I don't know what about you but for me this seems a little too complex to remember (I'm preparing for 12th grade exams). Although it surely does the job. Also can you explain or send a link to an answer why here, in "Stack Overflow" people tend to use "std::cout" over just "cout", Is it just for clarity? Thanks in advance. – BuderBrodas Jul 29 '20 at 10:28
  • @BuderBrodas about `std::cout` see [this](https://stackoverflow.com/q/1452721/10147399) – Aykhan Hagverdili Jul 29 '20 at 10:38
0

Adding '\0'-s to the end of the arrays would be hack.

And another hack that I see here is that you're trying to treat a two-dimensional array as a single-dimensional (you're passing arr[0] instead of something like arr[0][i]).
The reason that it somehow works, is that the cout just blindly reads the contents of the array until it meets '\0'.

You'd better avoid doing hacks, as you won't get a real benefit, but instead will decrease the readability and confuse the other guys who are working on that hacked code. ("Why there are some '\0'-s in the code?", they'll ask everytime).

To be short, just properly iterate on the array and print the characters:

for (int i = 0; i < 3; i++) {
    cout << abc[0][i];
}
cout<<endl;
Just Shadow
  • 10,860
  • 6
  • 57
  • 75
  • 1
    I don't think those are all that 'hacky'. Especially, indexing into a 2D array to get a 1D array is not a "hack"; it's just indexing... Also, I doubt anyone with any experience will question the presence of `\0` in things that are clearly text (not that it needs manually written if the array has enough extra space to add it automatically). – underscore_d Jul 29 '20 at 09:56
  • Treating 2-dimensional arrays as a single-dimensional is actually a hack. In other languages it would not even work. Here in c++ it just works because there are no restrictions and checks on dimensions and sizes of the arrays. Regarding the questions there are many questions that come to my mind when I see a hack. "Why don't we use array of strings instead of 2-dimensional array of chars with hacked \0 in the end?" Another question would be "Do we have any performance issues that we are trying to solve by this hacky code?" – Just Shadow Jul 29 '20 at 10:07
  • How is it a hack? A 2D array is an array of 1D arrays. Indexing into the 2D array yields a 1D array. What's wrong with that? There's no need to cast and no inherent loss of info or safety (excluding how one might pass the resulting 1D array to something that's not prepared for it). – underscore_d Jul 29 '20 at 10:22
  • Agreed, it yields 1D array underneath, that's just the way it's implemented. But if the language/compiler/interpreter doesn't restrict us to **misuse things**, it doesn't mean it's okay to do that. Creating a 2D array but using it as 1D is clearly misuse. Similarly in JS we can weirldy subtract a number from a string ("91"-1=90) in JS, and it would work just fine. But I guess we all understand that we should not be doing that :) – Just Shadow Jul 29 '20 at 10:49
  • I don't think your example is relevant and if indexing an array is considered a "Hack", there is no way to use that array in any meaningful way without being "Hacky". – Aykhan Hagverdili Jul 29 '20 at 10:50
  • I'm not sure I've understood the last comment. There is a way to do that "without being hacky", and the solution is just to normally iterate over the array. Btw if this conversation is going to be continued then let's open a chat on Stackoverflow and discuss it there (to avoid spamming here) – Just Shadow Jul 29 '20 at 11:04
  • I doubt a chat will change my mind that, if one has an array-of-arrays, indexing to an element of the array-of-arrays returns an array, & that doing the same is completely sensible & fine... – underscore_d Jul 29 '20 at 11:30