Array of strings

Hi,

I could create an array of strings (C++ strings) and fill each index with lines from a file, something like this:

#include <iostream>
#include <fstream>
#include <string>
#include <cstring>

int ReadFile (char *);
string * FillArray (char * , int );

int main()
{
//Read Number of items
int nbLines=0;
nbLines = ReadFile ("c:\\text.txt");
cout << "Number of lines = "<<nbLines<<endl;

//Copy items to array
string * strArray = 0;
strArray = FillArray("c:\\text.txt",nbLines);
delete [] strArray;
return 0;
}

string * FillArray (char * InputFileName, int nbElement)
{
ifstream InFile(InputFileName);
string Line;
int cnt = 0;
string * pStr = new string [nbElement];
//Copy Element in Array
while (getline(InFile, Line))
{
pStr[cnt] = Line;
cnt++;
}
InFile.close();
return pStr;
}

int ReadFile (char * InputFileName)
{
ifstream InFile(InputFileName);
string Line;
int cnt = 0;
//Count number of occurences
while (getline(InFile, Line))
{
cnt++;
}
InFile.close();
return cnt;
}

May be the memory allocation of the array (string * pStr = new string [nbElement];) is not at the right place but it works... Any comment will be appreciated...

But I am more concerned on how to do the same by using char * instead of string *?
So that the function would look like:
char * FillArray (char * , int );
or char ** FillArray (char * , int );
because we need a 2 dimensions array?


Thanks in advance,

Thanks,
Mustapha
Is there a reason why you are using arrays and not vectors?
Vectors are dynamic arrays and handle any memory deallocation for you.
And for as far as using char* you can always convert a string to a c_str (char*) by calling yourString.c_str(). This will return your sting as a char*.
Thanks Raggers for your reply,
I am not familiar with the vectors, but I will try it...
I was just wondering how I could do it with a more "c like" programming, that could help me to more understand the pointers...
If it is for learning pointers to multidimensional arrays you need to know that every array is the same, so char* can point to a array of any size or dimension. Doing so goes far beyond pointers.
And you need to know the dimension and size of all dimensions but the first to make and use it, that is why char array[][] is not legal and char array [][5] is.

If have been using C and C++ for the passed 4years or so and I don't even go there. :p

I'd say stay with vectors and don't try to reinvent the wheel.

Bud What's the reason for a more c like code?
And one more thing, if you are using a 2D array to store strings, the 2nd dimension has to be as big as the longest string. Meaning allot more memory use then needed, and if a even longer string comes along(say 6 chars longer) you need to increase the 2nd dimension by 6. This will result in a array using WAAAAAAAAAAAAAAAAAAAAY more memory then needed.

example a array of 30x30 is used to store a string of 38 chars long:

30 * 30 * sizeof(char) = 900bytes
31 * 38 * sizeof(char) = 1178bytes

meaning you spend 278bytes to store a string of 36 bytes.
I have no good reason trying to use "c like" code, it is just curiosity... I know about the memory it will take as I need at least the longest line to fit in a record... So you convinced me to use the vectors no doubts... But seeing the c solution will just make me sleep better :)
Have you ever encounter a situation where you cannot think about something else until you get it?
I tried again to create dynamically that 2D char* array but it looks like we cannot do that:
char * pStr = new char [30] [nbElement];

Thanks for your help and don't blame me if I am stubborn :)

Note: I am using this sample program to collect lines from a text file and reorder all lines by alphabetizing, then rewrite the file...
Select you code and press (<>) button before post next time, to get something like this..
1
2
3
4
5
6
7
8
9
10
11
12
13
//this is a comments
#include<iostream>
using namespace std;
int main(){
	int i=0;
	do{
	cout<<i<<endl;
	i=i+10;
	}while(i<=200);
    return 0;
    }

closed account (S6k9GNh0)
Raggers, the fact that a char* represents an array isn't that wild of an idea and as a matter of fact, is nothing more than a location in memory (a pointer). An array type is actually a reference pointer to the first element of the array. We can assign arrays to pointers but we cannot assign pointers to arrays (which is obvious if you think about it). An array, fundamentally, is nothing but a pointer (but not really) to the first element of the array but its treated differently, or like an array. The reason being is because its not actually a pointer but a type that signifies a block of data, an array.

We cannot make a pointer that points to a block of data that doesn't exist (yet), see? Check it out:
1
2
3
char * test1 = NULL;
char test2[10];
test2 = test1; /* Fail! This will not compile obviously! */


1
2
3
char * test1 = NULL;
char test2[10];
test1 = test2; /* The compiler casts the array type into a pointer we can use and toss around lightly! This compiles! */



When to use Vectors or C arrays
Vectors are incredibly useful when you do not know the maximum size of the given array. C arrays are incredibly useful with everything. In "most" situations, you can gander a maximum size for what you want and then cast that array into another array that perfectly fits the given amount of elements to save memory. This is actually REALLY ugly though and probably not the most optimized methods to go with so most of us choose to go with std::vector.
Last edited on
@ computerquip

I know that arrays are always pointers, I'm talking about transforming a pointer back to it's original array with multiple dimensions. To do this you need to know the dimensions and size of all dimensions but one to calculate the address of all elements as being a multiple dimension array. If you return a pointer to a 2x2 array you can use it as being a 1x4 but that's not what I mean by going far beyond just pointers to a array.

@MustaphaC:
To do this in a more c like code you can use something like this, but here the dimensions are fixed:

1
2
3
4
5
6
7
8
9
10
11
  char **p2DArray;
  // Allocate memory
  p2DArray = new char *[HEIGHT];
  for (int i = 0; i < HEIGHT; ++i) {
    p2DArray[i] = new char [WIDTH];
  }

  // Assign values
  p2DArray[0][0] = 'a';
  p2DArray[2][4] = 'b';


But I don't see a reason to do so unless you need to compile it in C and can't use C++.
Last edited on
@MustaphaC:

I'v been cleaning up my C memory and wrote you a example of how to do what you want in C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
void aArray (char* array[], int& size)
{
	array = new char* [10]; // create a array of 10 char*.
	size = 10; // set the return size of the array.
	for (int i = 0; i < 10; ++i)
	{
		array[i] = new char [SIZE_OF_STRING]; // have array[i] point to a array of SIZE_OF_STRING chars.

		//Copy the string to the new array.
		for(int p = 0; p < 20; p++)
		{
			array[i][p] = CHAR_P_OF_STRING;
		}
	}

}
int main()
{
	int sizeD1;
	char** strings;
	aArray(strings, sizeD1);

	int* sizeD2 = new int[sizeD1];
	for (int i = 0; i < sizeD1; i++)
	{
		sizeD2[i] = sizeof(strings[i]) / sizeof(char);
	}

	// At this point sizeD1 will have the size of dimension 1 and sizeD2[x] the size of the array at position x (2nd dimension)
	for (int i = 0; i < sizeD1; i++)
	{
		for (int p = 0; p < sizeD2[i]; p++)
		{
			// use strings[i][p]...
		}
	}
}


In this code you make a 2D array of char where the size in the 2nd dimension is only as long as needed for the string you store at position x in the 1st dimension.

(note: char* array[] is the same as char** array, but char* array[] is used to make the code more readable. And you can do char** aArray (int& size) to return the array if you like but I'v seen it more often as being a parameter then a return.)
Wow! Thank you very much Raggers. I was away from such a solution but now you opened my eyes... And I can now think about other methods...
I will now study the Vectors and compare things, that is how we progress, no?
Thanks again!
Unless you can only use C, there is no reason not to use vectors.
And they are allot safer to use to since they'll handle all memory allocation and deallocation for you.
Topic archived. No new replies allowed.