First recommendation: never do like this
for (int j = 0; j < strlen(ie); j++) { /* do something */ }
Do it like this instead:
for (int i = 0; ie[i] != '\0'; ++i) { /* do something */ }
or
int ie_len = strlen(ie);
for (int j = 0; j < ie_len; ++j) { /* do something */ }
because each loop condition check it calls strlen
which takes length of string to calculate this function, so it takes square of string length in first case
I recommend use std::string
and std::vector
to store 2D array of strings, and avoid raw pointers and especially new
operator (at least for code in question body you forgot delete
for this new's). If you really want mess with raw pointers, see the end of this answer, but now recommended way to do what you want (as I understand what you want):
#include<iostream>
#include<string>
#include<vector>
using namespace std;
int main()
{
int M = 4;
int N = 4;
std::vector<std::vector<std::string>> A(M);
char ie[20];
for (int i = 0; i < M; i++) {
A[i] = std::vector<std::string>(N);
}
// can be used std::fill(A.begin(), A.end(), std::vector<std::string>(N)); instead for loop above but for loop simplier to understand
cout << "Row num" << endl;
int row = 0;
cin >> row;
cout << "Row col" << endl;
int col = 0;
cin >> col;
string temp;
cout << "Item" << endl;
cin >> temp;
A[row][col] = temp;
for (int i = 0; i < M; i++)
{
cout << std::string(N * (temp.size() + 3) + 1, '-') << "\n"; // add separator to be clear what happening
cout << "| "; // add separator to be clear what happening
for (int j = 0; j < N; j++) {
A[i][j].resize(temp.size(), ' '); // for all columns has equal width to be clear what happening
cout << A[i][j] << " | ";
}
cout << endl;
}
}
example of input and output of this code:
Row num
1
Row col
2
Item
bob
-------------------------
| | | | |
-------------------------
| | | bob | |
-------------------------
| | | | |
-------------------------
| | | | |
Messing about raw pointers
(your code with some editions and useful comments):
#include<iostream>
#include<cstring> // cstring not string as @PaulMcKenzie mentioned in comments for strlen
using namespace std;
int main()
{
int M = 4;
int N = 4;
char *item;
char ie[20];
// dynamically create an array of pointers of size `M`
const char*** A = new const char**[M]; // need add one more star because two for two-dimensonal array and one more for ~string~(aka char array)
// dynamically allocate memory of size `N` for each row
for (int i = 0; i < M; i++) {
A[i] = new const char*[N];
}
const char empty_string[1] = "";
for (int i = 0; i < M; ++i){
for (int j = 0; j < N; ++j){
A[i][j] = empty_string; // make empty names on all shelves
}
}
cout << "Row num" << endl;
int row = 0;
cin >> row;
cout << "Row col" << endl;
int col = 0;
cin >> col;
//string temp;
cout << "Item" << endl;
cin >> ie;
/*not need this:
for (int j = 0; j < strlen(ie); j++)
{
A[row][col] = ie[j];
}
just save adress like this:*/
A[row][col] = ie;
int ie_len = strlen(ie);
/* can be done simply:
for (int i = 0; i < M; i++)
{
for (int j = 0; j < N; j++) {
cout << A[i][j] << " ";
}
cout << endl;
}
but it doesn't look like table*/
// add seprators for understanding what happenning
for (int i = 0; i < M; i++)
{
// add horizontal separator
for (int j = 0; j < N * (strlen(ie) + 3) + 1; ++j){
cout << "-";
}
cout << "\n";
cout << "| "; // add separator to be clear what happening
for (int j = 0; j < N; j++) {
cout << A[i][j];
// for equal width of columns add some spaces
for (int k = strlen(A[i][j]); k < ie_len; ++k){
cout << " ";
}
cout << " | ";
}
cout << endl;
}
// not forget to delete all what u newed
for (int i = 0; i < M; i++) {
delete A[i];
}
delete A;
}