0

I am trying to make a program where it asks the user the number of shelves and number of positions on those shelves from the user then it asks the user where he wants to enter a product. Now I got rows and columns figured out but I can't get the full product name printed it just shows a single character of said product. Is there a way I can store an address of a string variable and store it in that column of my row to print the complete word? This is what I have done so far.

#include<iostream>
#include<string>
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`
    char** A = new char*[M];

    // dynamically allocate memory of size `N` for each row
    for (int i = 0; i < M; i++) {
        A[i] = new char[N];
    }
    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;
    
        for (int j = 0; j < strlen(ie); j++)
        {
            A[row][col] = ie[j];
        }
    

    for (int i = 0; i < M; i++)
    {
        for (int j = 0; j < N; j++) {
            cout << A[i][j] << " ";
        }
        cout << endl;
    }

}

sorry If the question is not clear or easy to understand.

CHAHI Saad
  • 309
  • 4
  • 15
Qadees PC
  • 13
  • 4
  • 1
    Is there any reason why you cannot use `std::string`? – Costantino Grana Jan 29 '22 at 10:33
  • 4
    `std::vector A(M);` -- Once you do that and use this, then all of those other issues go away. -- *Is there a way i can store an address of a string variable* -- There are no string variables in the code you posted. You have `char *`, and those are just pointers. If you want a string type, then `std::string` is the string type. – PaulMcKenzie Jan 29 '22 at 10:36
  • 1
    `A[row][col]` is one character, which you assign `ie[j]` to multiple times. Its value after the loop is `ie[strlen(ie)-1]`. – molbdnilo Jan 29 '22 at 10:39
  • `#include` -- This defines `std::string`, but your code failed to use any of it. The functions `strlen`, etc. are in ``, not `` – PaulMcKenzie Jan 29 '22 at 10:40

1 Answers1

0

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;
}
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459