Hi,
Long time lurker, first time poster.
I have been working on this assignment for days and keep getting stuck. I am supposed to read the contents of a text file (first and last names, e.g. Smith, John ) into a two dimensional array, sort the array, and write it to a new file. Names longer than 25 characters are supposed to be truncated.

I am storing the names in a character array of pointers, I am able to input the names into the array but as soon as my while loop exits my array is totally messed up.

Here's my code:

Code:

//Names are found in the file "names.txt"

#include <iostream>

using std::cout;
using std::cin;
using std::ios;
using std::cerr;
using std::endl;

if (!outFile ) { //if file could not be opened display error and exit
cerr << "File could not be opened." << endl;
exit( 1 );
}

while ( row < num ) { //output names to file while number of names is greater than counter

cout << n[row][0];
outFile << n[row][0] << endl;

row++; //increase counter

}

}

I will be so grateful if you can give me some advice.

Thank you! Jenna

12-03-2004

CornedBee

Are you allowed to use std::string? I would highly recommend doing so, it would free you of all memory management troubles.

12-03-2004

Hunter2

I notice that you're using the assignment operator (=) to assign values to 'strings', and comparing them using the > and < operators. The problem is, you can't do this in C++. You can use strcpy() to copy strings and strcmp() to compare them (in <cstring>), but then you have to worry about making sure that the strings are large enough to hold whatever you put in them, etc.

The easiest solution I can think of, is to use std::string (include <string>) instead of char* or char[], since it actually does work with the =, ==, <, > operators - and std::string automatically resizes itself to fit the contents of the string, and cleans up after itself, i.e. frees its own memory.

12-03-2004

elad

Your sortFile looks like an attempt to implement a bubble sort. I'd recommend you do a board search or a google search to find a variety of ways to implement this type of sort.

If you can't use std::string class and you have to use char * then the procedure in rough pseudocode could be something like this:

void sortFile( char n[10][26], int num )
{
//external loop to determine number of times to run through the array
//internal loop to compare each name in the array with each other name in the array
//use result of strcmp(n[i], n[i+1]) to determine whether to swap or not.
//if swapping, use something like
char tmp[26]; //maximum 25 useable char + null
strcpy(tmp, n[i + 1]);
strcpy(n[i+1], n[i]);
strcpy(n[i], tmp);

12-03-2004

jenna

Thanks for the advice everyone.

The assignment says that I have to use a two dimensional array to hold the names. Can I still use std::string and maybe use the array to hold pointers to the strings? Any other way to use a two dimensional array for this besides pointers?

Jenna

12-03-2004

CornedBee

std::string names[25][2];

This will work just fine.

12-03-2004

elad

char n[10][26];

n is a two dimensional array of type char that can hold up to 10 different C style strings, each of which can hold up to 25 useable char and a single null terminating char. Note that there is no * in the declaration. You could substitute a single * for a single [] if you wish, and declare memory for that * using the heap rather than the stack, but I interpret

char * n[10][26];

to be a pointer to a two dimensional array of char, rather than a two dimensional array of char.

std::string n[26];

is an array of 26 std::strings, and not a two dimensional array as far as I'm concerned.

std::vector<std::string> n;

is a vector of strings and, again, not a two dimensional array of strings. This despite the fact that string n[26] and vector<string> n could both make your life easier.

BTW I think

n[i][0]

is a single char rather than a string if n is declared as follows:

char n[10][26];

n is the pointer to n[0][0], n[i] is a given string in n, &n[i][0] is the address of the first char of a given string and could be used like n[i] but the syntax is terrible cumbersome. I still find all this somewhat confusing myself, but if I've led you astray I'm sure someone will get us back on the road to (somewhere).

12-03-2004

CornedBee

Quote:

but I interpret

char * n[10][26];

to be a pointer to a two dimensional array of char, rather than a two dimensional array of char.

That's a two-dimensional array of pointer to char.

Basically, try to avoid having more than one dimension, especially when dealing with strings. Since your assignment apparently requires you to have two dimensions, at least use std::string to avoid big memory confusions.

If the assignment allows it, you could also use std::sort to sort the array. But since it's 2dim, you would have to write your own sorting predicate (comparator).

12-04-2004

elad

char names1[10][26] would hold 10 strings of up to 25 useable char. Each string would be a single name, like "Ebekeneezer" or "Smythe, Jane".

strcpy(names1[0], "Smythe, Jane");

std::string names2[10][2] would hold 10 groups of strings each group having two strings of unlimited (except by available memory) size. I could see this working well if you wanted to recognize the first name and the last separately, like:

names2[0][0] = "Smythe";
names2[0][1] = "Jane";

If you wanted to hold first and last names separately, each name could only be 25 char long and you couldn't use std::string, then you could try:

Apparently names1, names2, and names3 would all be two dimensional arrays with names1 being a two dimensional array of char, names2 being a two dimensional array of std::string and names3 being a two dimensional array of char pointers.

However, names1 is what I think of when I think of a two dimensional array used to hold names. That's because in order to get an individual char (say the first char of the initial name in each array) I only need to go two levels deep in names1:

char ch1 = names1[0][0];

whereas in names2 I would need to do this:

char ch2 = names2[0][0][0];

and in names3 I believe I could also do this:

char ch3 = names3[0][0][0];

In other words, to me, names2 and name3 are really doing this under the hood:

char names4[10][2][26];

(which is clearly a three dimensional array of char) except names2 doesn't have the size restriction of 26 on the third level of indirection. Since I have no idea what your instructor really wants, I guess it's up to you to make the decision which way you want to go in "using a two dimensional array to hold the names".