Converting 1d array output to look like a matrix

Hey ya'll, I'm trying to print a 1d array as a [5][5]2d matrix. I started off by creating a char array which hold 25 elements, I then created a pointer to a char array in order to grab the values from the array. I plan to create methods that will use the pointer to manipulate the array. I just wanted to start off by making sure the array was displayed how I wanted it to be. Any tips will help.

What I have tried:
I tried to create nested for loops in order to display the first 5 elements, skip a line, display 5 elements, skip a line, until the whole array is read. But my program output nothing but gibberish.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

int main()
{
    //Creating a 1d char array
    char my_array [] = "sweetheartegritcloneodors";
    //Create a pointer to a char
    //initialize it to point to my_array
    char *ptr = my_array;
    
    for(size_t j=0; j<25; j++){
        cout<<setw(2)<<*(ptr);
        ptr++;
        
    }

    cout << endl;
    
   // cout<< *ptr;
    return 0;
}


The output should look like:

s w e e t
h e a r t
e g r i t
c l o n e
o d o r s
Last edited on
there are a couple of ways. since you used array, you can just cast it to 2-d -- this works because is solid block (** won't work, for example, as each sub pointer can be far from its buddy in memory). This kind of casting is kind of C-ish / low level stuff that is not generally seen in c++ anymore.

you can also print using the formula:
x[desired row][desired col] is the same as x[desired_row*numcolumns+desired_column]

finally you can just print 5 and do a return in the printing.
Last edited on

finally you can just print 5 and do a return in the printing.


Sorry I'm a beginner so I could sound like a noob. Are you saying to print 5 elements, then continue printing where I started off. Because that's initially what I wanted to do.
Would it be possible to create a while loop that prints out the first 5 elements, adds a newline, and continues to print out the rest of the array in that format until it reaches the end of the array?
Okay, so I was able to get this, but I can't explain the gibberish it outputs at the end.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int main()
{
    //Creating a 1d char array
    char my_array [] = "sweetheartegritcloneodors";
    //Create a pointer to a char
    //initialize it to point to my_array
    char *ptr = my_array;
    
    for(size_t i=0; i<sizeof(my_array); i++)
    {
        for(size_t j=0; j<5; j++){
            cout<<setw(2)<<*(ptr);
            ptr++;
            
        }
       
        cout<<endl;
    }
You're incrementing the pointer 5 times per every character you iterate over, so you're going past the end of your array.

It would be a lot simpler to just stick to a single loop, and add new lines.

1
2
3
4
5
6
7
8
for (size_t i = 0; i < sizeof(my_array); i++)
{
    cout << *(ptr + i) << ' ';
    if (i % 5 == 4)
    {
        cout << '\n'; // every 5th character, print a newline
    }
}
Last edited on
Ahhh, is that what they mean by C++ does not perform bounds checking?Was that gibberish I saw just random stuff in memory? And it worked by the way, thank you.
Correct, no bounds checking is done on the array indices.
So if you have an array with 5 elements in it, and you attempt to access its 100th element, you are going out of bounds.

Yes, you essentially saw random stuff in memory.*

But as far as C++ goes, accessing an invalid array index is undefined behavior. Sometimes, junk might be printed. In other scenarios, your program might crash, so don't do it!

*of course, it's a bit more complicated than this (every program has a separate virtual address space, so you are limited in what you can just "randomly" see.) (It's most likely that you'll crash after you've gone past a page in memory, but it is not behavior to be relied on.)
___________________________

Some extra details, don't worry about these, just in case you're curious:

- Note that *(ptr + i) is equivalent to ptr[i] for arrays/pointers. ptr[i] is "syntactic sugar". Prefer the ptr[i] syntax as it's usually regarded as easier to read (but sometimes for a school assignment where you're told to use pointers, they make you use the pointer syntax).

- Use of sizeof in this manner is discouraged. Starting in more recent versions of C++, there is a function called std::size, e.g. std::size(my_array), and this safer to use. Note that for arrays of types except char, you should do size_t num_elements = sizeof(my_array)/sizeof(*my_array); -- it happens to not matter in this case because sizeof(char) is always 1.
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <iomanip>

int main()
{
    char my_array [] = "sweetheartegritcloneodors";
    char *ptr = my_array;
    size_t size = sizeof(my_array)/sizeof(my_array[0]); // or std::size ... whatever
    
    size_t count{0};
    while(count < size)
    {
        std::cout << std::setw(2) << *(ptr);
        ptr++;
        count++;
        
        if( count % 5 == 0)
            std::cout << '\n';
    }
    std::cout << '\n';
    
    return 0;
}



 s w e e t
 h e a r t
 e g r i t
 c l o n e
 o d o r s
 
Program ended with exit code: 0


Can just use std::copy()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <iterator>

int main()
{
	constexpr char my_array[] = "sweetheartegritcloneodors";	// Don't forget includes terminating \0 !
	constexpr size_t perrow {5};

	static_assert((std::size(my_array) - 1) % perrow == 0);

	for (auto it = std::begin(my_array); it < std::end(my_array) - 1; it += perrow) {
		std::copy(it, it + perrow, std::ostream_iterator<char>(std::cout, " "));
		std::cout << '\n';
	}
}

1
2
3
4
5
6
7
8
9
#include <iostream>
using namespace std;

int main()
{
   char my_array[] = "sweetheartegritcloneodors";
   const int cols = 5;
   for ( char *p = my_array; *p; p++ ) cout << *p << ( ( p - my_array + 1 ) % cols ? ' ' : '\n' );
}
Oceanspray,
vectors, and other stl containers, which are the majority of what is used in c++, do have optional bounds checking. For performance reasons, it is not FORCED upon the programmer to do that -- its wasted cpu cycles for nothing when you know you have 10 things and loop 10 times, checking 10 times is just slow and pointless.
The .at() on vectors checks bounds. the [] operator does not. Its up to the programmer to decide if bounds checking is required.

what 'they' probably mean is that its not enforced. Some languages assume the programmer is unskilled and check everything behind the coder, which is exceedingly slow but safer. There is a time and a place for that. If nothing else, once technology stops being able to make better cpus, we can still get about 10x speed increase by writing tight code :P
Last edited on
And that’s not to forget the speed increases that can be achieved by using the largely un-tapped resource of parallel programming, particularly useful where loops are involved.
Topic archived. No new replies allowed.