Antonella Masini Antonella Masini - 14 days ago 4
C++ Question

C++ Displaying a string (with blank spaces) into a two dimensional array?

I know that there are already several questions answered about this topic but none of them could help me solve my problem. Please, have in mind that I have just started learning C++ Programming.

I am creating a program that reads a text and then displays it in N rows x M columns (entered by the user). So, if the user writes HarryPotter and wants it to be displayed in a 3 x 4 array it should look something like this:

H a r r
y P o t
t e r


I have already manage to do so with this code:

cout << "Number of rows: ";
cin >> nr;
cout << "Number of columns: ";
cin >> nc;
cout << "Type in text: ";
cin >> text;

char letters[100][100];

for (int row = 0; row < nr; row++)
{
for (int col = 0; col < nc; col++)
{
letters[row][col]= text [i];
i++;
}
}

cout << "Print array: " << endl;
for (int row = 0; row < nr; row++)
{
for (int col = 0; col < nc; col++)
{
cout << letters[row][col];
}

cout << "\n";
}


And it works fine until the user writes more than one word. For example instead of HarryPotter he writes Harry Potter (I think that the blank spaces between the words is what creates the problem). Do you know why this happens and how can I solve it? Thank you very much.

Answer

The problem is that the operator >> stops entering a string when a white space character is encountered in the stream. You should use standard function std::getline instead.

Take into account that to display a string there is no need to define an array. The task can be done without using an array.

Here is a demonstrative program.

#include <iostream>
#include <string>
#include <limits>
#include <algorithm>

int main() 
{
    while ( true )
    {
        std::cout << "Number of rows (0 - exit): ";

        unsigned int rows;
        if ( not ( std::cin >> rows ) or ( rows == 0 ) ) break;

        std::cout << "Number of columns (0 - exit): ";

        unsigned int cols;
        if ( not ( std::cin >> cols ) or ( cols == 0 ) ) break;

        std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );

        std::cout << "Type in text: (Enter - exit): ";

        std::string text;
        std::getline( std::cin, text );
        if ( text.empty() ) break;

        std::cout << std::endl;

        std::string::size_type n = text.size();

        n = std::min<std::string::size_type>( n, cols * rows );

        for ( std::string:: size_type i = 0; i < n; i++ )
        {
            std::cout << text[i];

            std::cout << ( ( i + 1 ) % cols == 0 ? '\n' : ' ' );
        }

        std::cout << std::endl;
    }

    return 0;
}

Its output might look like

Number of rows (0 - exit): 3
Number of columns (0 - exit): 4
Type in text: (Enter - exit): HarryPotter

H a r r
y P o t
t e r

Number of rows (0 - exit): 2
Number of columns (0 - exit): 6
Type in text: (Enter - exit): HarryPotter

H a r r y P
o t t e r 

Number of rows (0 - exit): 6
Number of columns (0 - exit): 2
Type in text: (Enter - exit): HarryPotter

H a
r r
y P
o t
t e
r 

Number of rows (0 - exit): 4
Number of columns (0 - exit): 4
Type in text: (Enter - exit): Antonella Masini 

A n t o
n e l l
a   M a
s i n i

Number of rows (0 - exit): 0

You may substitute this statement

if ( not ( std::cin >> rows ) or ( rows == 0 ) ) break;

for this statement

if ( !( std::cin >> rows ) || ( rows == 0 ) ) break;

if the compiler does not compile the first statement. If you use MS VC++ then in the properties of the project you should switch off using of the language extensions (C++, language), and the statement will be compiled.

Comments