Hello ladies and gents,

I'm trying to output a 2D array, but can't seem to find the solution, can anyone help me out here.

#include <stdafx.h>
#include <iostream>

using namespace std;

int main()
{
	int **pp;
	int i, j, n, ni;

	cout<<"Geef het aantal regels als volgt: ";

	cin>> n;
	pp = new int *[n];

	for (i = 0; i < n; i++)
	{
		cout<<"Geef ni, de lengte van de eerstvolgende regel: ";
		
		cin>> ni;
		pp[i] = new int[ni];

		cout<<"Tik "<< ni <<" getallen in:\n";

		for(j = 0; j < ni; j++)
		{
			cin>> pp[i][j];
		}
	}

	for(i = 0; i < n; i++)
	{
		ni = sizeof ?????
		for(j = 0; j < ni; j++)
			cout<< pp[i][j] <<" ";
		cout<<endl;
	}

	for(i = 0; i < n; i++)
		delete[] pp[i];

	delete[] pp;

	cout<<"Press any key to quit!\n";cin.get();

	return 0; 
}

I know I have to use the size of each row of the array, but fail to see wich piece of code I have to use to write next to sizeof

for(i = 0; i < n; i++)
	{
		ni = sizeof ?????
		for(j = 0; j < ni; j++)
			cout<< pp[i][j] <<" ";
		cout<<endl;
	}

Any help would be greatly appreciated :)

You'll need to keep track of each size entered by the user.

Hi Dave,

Well, I tried to use this piece of code

pp[i] = new int[ni];

detemines how many there would be entered in each row of the array, I suspect(ed) that it was this what I needed.

But when I write

ni = sizeof pp[i];

my output four numbers in each row, if I entered more then four, they are not in the row of the array they supposed to be in.

If I enter less, it's filled up with random number (rubbish) :?:

I'm baffled, because, I don't know what else I should use other then that piece of code :confused:

You will need to keep track of the size of each row yourself. As another variable. Or a different data structure.

Got it :D

Thanks Dave :!: Now, that's what I call, good TIPS ;)

for (i = 0; i < n; i++)
	{		
		cout<<"Geef ni, de lengte van de eerstvolgende regel: ";

		cin>>ni;
		pp[i] = new int[ni];
		teller[i] = ni;

		cout<<"Tik "<< ni <<" getallen in:\n";

		for(j = 0; j < ni; j++)
			cin>> pp[i][j];
	}

	for(i = 0; i < n; i++)
	{
		for(j = 0; j < teller[i] ;j++)
		{
			cout<< pp[i][j] <<" ";
		}
		cout<<endl;
	}

Is there another way I could have solved this, besides using STL <vector> ?

Is there another way I could have solved this, besides using STL <vector> ?

Sure. Like I said, you could use a different data structure.

//#include <stdafx.h>
#include <iostream>

using namespace std;

int main()
{
   int i, j, n;
   struct row
   {
      int *col, size;
   } *pp;

   cout<<"Geef het aantal regels als volgt: ";

   cin>> n;
   pp = new row[n];

   for ( i = 0; i < n; i++ )
   {
      cout<<"Geef ni, de lengte van de eerstvolgende regel: ";

      cin>> pp[i].size;
      pp[i].col = new int[pp[i].size];

      cout<<"Tik "<< pp[i].size <<" getallen in:\n";

      for ( j = 0; j < pp[i].size; j++ )
      {
         cin>> pp[i].col[j];
      }
   }

   for ( i = 0; i < n; i++ )
   {
      for ( j = 0; j < pp[i].size; j++ )
         cout<< pp[i].col[j] <<" ";
      cout<<endl;
   }

   for ( i = 0; i < n; i++ )
      delete[] pp[i].col;

   delete[] pp;

   cout<<"Press any key to quit!\n";cin.get();

   return 0;
}

/* my output
Geef het aantal regels als volgt: 3
Geef ni, de lengte van de eerstvolgende regel: 4
Tik 4 getallen in:
1 2 3 4
Geef ni, de lengte van de eerstvolgende regel: 2
Tik 2 getallen in:
5 6
Geef ni, de lengte van de eerstvolgende regel: 3
Tik 3 getallen in:
7 8 9
1 2 3 4
5 6
7 8 9
Press any key to quit!
*/

Wow, thanks for that example.

Few questions Dave if you don't mind.

1) Am I correct that you wrote the structure inside main so you could get to its members directly?

2) One thing I don't understand, because I actually haven't seen it yet is this

struct row
   {
      int *col, size;
   } *pp;

Why is written outside the structure but yet inside the ; ?

3) You allways show your output in the manner as above, how do you do this, is this something you can let your compiler do?

4) When would you prefere your solution towards mine? For more complicated programs, so that, it actually becomes less complicated?

1) No, a structure's members are public by default, so anyone can access them. Dave put the structure in main to limit its scope to main. Consider this:

int main()
{
  struct test {};
  test t; // Okay, test visible
}

int foo()
{
  test t; // Error! test not visible outside main
}

2) That's a declaration of pp, a pointer to struct row. You can split it up by the type and the identifier, and compare it with an integer to see the similarities:

Type                            Identifier
------------------------------  ----------
struct row {int *col, size;} *  p;
int                             x;

The only difference is that int already exists while struct row is being defined.

3) You can cut and paste from the output medium, such as the console, or redirect the output to a file. It really depends on your system and compiler.

4) Dave's solution makes use of simple objects. Each row object has an array and also stores the size of that array. In all but the most trivial of programs, this solution has the benefit of simplicity.

1) Yep, that made it perfectly clear :!:

2) In other words, it means that *pp has those properties wich are mentioned in the structure right :?:

And can only a pointer have that ability to be written in that place :?:

What is the difference then when writing a structure, like this

struct row
{
      int *col, size;
};

int main()
{
      row pp;
...
}

and this:

struct row
{
      int *col, size;
}*pp;

int main()
{
      pp;
...
}

Because, the first example also gives the properties of the structure to the object pp right?

3) Well, Ive tried cutting and pasting, but, it doesn't work when the exercise is executed? Could you tell me how I can make it redirect towards the output of a file?
System is Windows XP Pro and compiler is VC++ 6.0

4) Well, I guess it depends on what you call simple right :o But, I do think I get the picture with you're explanation and Dave's code example, I think ;)

> In other words, it means that *pp has those properties wich are mentioned in the structure right
Yea, basically.

> And can only a pointer have that ability to be written in that place
No, you're just declaring a variable. It's the same thing as this:

struct row
{
      int *col, size;
};

row *pp;

> What is the difference then when writing a structure, like this
pp is local to main in the first example, but has file scope and external linkage in the second.

> Could you tell me how I can make it redirect towards the output of a file?
If you run the program from the command line you can do this:

C:\> prog > file
C:\> type file

Or you can redirect to a file from directly in within the program. First by using the file stream instead of cout:

#include <fstream>

int main()
{
  std::ofstream out("file");

  out << "output\n";
}

Or by re-assigning the stream buffer of the file stream to cout:

#include <fstream>

int main()
{
  std::ofstream out("file");
  std::streambuf *saved_buff = std::cout.rdbuf();

  std::cout.rdbuf(out.rdbuf());

  std::cout << "output\n";

  std::cout.rdbuf(saved_buf);
}

> Well, I guess it depends on what you call simple right
Yea. :mrgreen: Simple for me may not be simple for you, and vice versa depending on the problem. Nobody knows everything. :)

Thanks for the explanation Dogtree, Ive been trying to get the output to work and if I'm correct, I assume that in the part of

std::ofstream out("file");

I have to put the place where the output should be saved to correct?

Well, Ive tried this with the following path

std::ofstream out("C:\Documents and Settings\Johan Berntzen\Mijn documenten\Mijn ontvangen bestanden\VCPrograms");

The problem is that I'm getting the following warnings :confused:

C:\Program Files\Microsoft Visual Studio\MyProjects\Testing\Testing.cpp(11) : warning C4129: 'D' : unrecognized character escape sequence
C:\Program Files\Microsoft Visual Studio\MyProjects\Testing\Testing.cpp(11) : warning C4129: 'J' : unrecognized character escape sequence
C:\Program Files\Microsoft Visual Studio\MyProjects\Testing\Testing.cpp(11) : warning C4129: 'M' : unrecognized character escape sequence
C:\Program Files\Microsoft Visual Studio\MyProjects\Testing\Testing.cpp(11) : warning C4129: 'M' : unrecognized character escape sequence
C:\Program Files\Microsoft Visual Studio\MyProjects\Testing\Testing.cpp(11) : warning C4129: 'V' : unrecognized character escape sequence

I'm undoubtedly doing something wrong, Ive changed the letters to 'small size'( <-- don't know the English word for this) but, it gives the same warnings so, I'm sure it's not related towards using big or small size letters.

The program code I used is similar to what you wrote:

#include <iostream>
#include <fstream>

using namespace std;

int main()
{
	std::ofstream out("C:\Documents and Settings\Johan Berntzen\Mijn documenten\Mijn ontvangen bestanden\VCPrograms");
	std::streambuf *saved_buff = std::cout.rdbuf();

	std::cout.rdbuf(out.rdbuf());

	std::cout<< "output\n";

	std::cout.rdbuf(saved_buff);

	cout<<"Kopieer dit eens!"<<endl;
	
	cout<<"Press any key to continue!\n";cin.get();

	return 0; 
}

Use forward slashes.

std::ofstream out("C:\Documents and Settings\Johan Berntzen\Mijn documenten\Mijn ontvangen bestanden\VCPrograms");

These would be exotic escape sequences.

Well, changed it towards forward slashes and not getting any error messages anymore, problem is, the path where it is pointed at, doesn't get any file loaded into it :confused:

I thought when I would write it like this:

#include <iostream>
#include <iomanip>
#include <fstream>

using namespace std;

int main()
{
	int i;

	std::ofstream out("C:/Documents and Settings/Johan Berntzen/Mijn documenten/Mijn ontvangen bestanden/VCPrograms");
	std::streambuf *saved_buff = std::cout.rdbuf();

	std::cout.rdbuf(out.rdbuf());


	for (i = 0 ; i < 10; i++)
	{
		std::cout<< setw(2) << i <<endl;
	}

	std::cout.rdbuf(saved_buff);

	cout<<""<<endl;cin.get();

	return 0;
}

I would find a file in VCPrograms with the output: 0 1 2 3 4 5 6 7 8 9

Sorry Dave, I found it, I created this map VCPrograms, wich is the map that has to contain all the files with output. But, ofcourse, you have to give each file it's own name wich I didn't at first :o

std::ofstream out("C:/Documents and Settings/Johan Berntzen/Mijn documenten/Mijn ontvangen bestanden/VCPrograms/Test1");

Haven't figured out how this one works though

C:\> prog > file
C:\> type file

:?:

Do I have to enter the same path wich it has to follow as in the other ones?

Thanks for the help ;)

JoBe,

I would suggest STL <vector>.

Take care,
Bruce

> Do I have to enter the same path wich it has to follow as in the other ones?
Yes. For simplicity, my example assumed that both the executable program and the file were local to the root directory C:\, but unless your current working directory is the same as the executable and the output file, you need to specify an absolute path.

@ BruceWilson512,

Thanks for the tip, you mean something like this:

int main()
{
	int n, ni, i ,j;

	typedef vector<int> rij;

	cout<<"Geef het aantal regels dat volgt: ";
	cin>> n;

	vector<rij> v(n);	// vector van n rijen

	for (i = 0; i < n; i++)
	{
		cout<<"Geef ni, de lengte van de eerstvolgende regel: ";
		cin>> ni;

		cout<<"Tik " << ni <<" getallen in:\n";

		for (j = 0; j < ni; j++)
		{
			int x;
			cin>> x;
			v[i].push_back(x);
		}
	}

	cout<<"De volgende rijen zijn ingelezen:\n"<< fixed <<endl;

	for (i = 0; i < n; i++)
	{
		ni = v[i].size();

		for (j = 0; j < ni; j++)
		{
			cout<< setw(6) << v[i][j] <<" ";
		}
		cout<<endl;
	}
	
	cout<<"Press any key to quit!" <<endl;cin.get();

	return 0; 
}

Above code was given as an example and wasn't written by myself!

Now, I understand the above code and have a fairly good idea what typedef is doing, as it let's 'rij' be a vector on it's own correct?

But, what would I have to change to let this code work without the use of typedef?

I asume I have to make another vector from 'rij' then right?

@ Dogtree,

Would it be something like this then?

C:\> Documents and Settings/Johan Berntzen/Mijn documenten/Mijn ontvangen bestanden/VCPrograms> Test1
C:\> Test1

Also, do I need to use forward or backward slashes?

> Would it be something like this then?
Something like that, yea. But wouldn't it be faster to try it out for yourself? ;)

> Also, do I need to use forward or backward slashes?
Either will work from the shell. The only issue with back slashes is in C++ where they are the escape for special characters in string literals.

>Something like that, yea. But wouldn't it be faster to try it out for yourself? ;)

How very true, but STL is chapter 10 :mrgreen: I'm at chapter 6 ;)

The author of the book showed a few examples in using STL and standard code! Had to do a few exercises with STL in chapter 5, but will be extended much more in chapter 10 :!:

Bye the way, I wouldn't dare to say that I could do it faster then what is written in that book you know :mrgreen:

Infact, can you tell me in wich type of programs you use STL regularly, I mean, is it used in games, embedded systems, .... ?

>Either will work from the shell. The only issue with back slashes is in C++ where they are the escape for special characters in string literals.

Understood, only, what do you mean with the expression "from the shell"?

> How very true, but STL is chapter 10. I'm at chapter 6
What are you talking about? The STL has nothing to do with redirecting the output of a program to a file from the shell. If you were talking about the vector suggestion then you really need to work on formatting your quotes so that it's obvious which quote goes with which question.

> can you tell me in wich type of programs you use STL regularly
All of them.

> Understood, only, what do you mean with the expression "from the shell"?
Shell, terminal, command line, that black thingy with white text that you type and it does stuff.

>What are you talking about?
My mistake ;)

... that black thingy with white text that you type and it does stuff.
OH, NOW I understand :D

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.