Reading an Array of Strings from a File

I am attempting to read strings from a file into a 2D array.  My code so far is as follows:

#include <iostream.h>
#include <fstream.h>
#include <cstring>


int main()
{
     // open file for reading and assign to array values
     
     char buffer[100];               // buffer to store read names
     char *name[1000];               // array of names
     int index = 0;                    // index for each name

     ifstream file("names.txt");
     
     if (! file.is_open())
     {
          cout << "Error opening file";
     }

     else
     {
          while (! file.eof())
          {
         
          file.getline (buffer, 100);
          cout << buffer << endl;
          strcpy(name[index], buffer);
          index++;

         
          }
     }
     
     return 0;

}

Everything works fine except the "strcpy(name[index], buffer)" line.  That line gives me a memory error.  I need the strings indexed in an array so I can later sort, search, etc. the data.  This code sample looks like it should be pretty easy, but as a C++ newbie I'd appreciate any help concerning the specific problem I'm having with the name[index], as well as any tips concerning format, etc.  Thanks.
SidVicAsked:
Who is Participating?
 
AxterConnect With a Mentor Commented:
I recommend that you not use any *.h C++ standard library files in your code.  The *.h STL headers are NOT part of the C++ standard, and therefore are not portable.  There also less reliable in general.

I also recommend that you use std::string instead of the old C-Style strings.  That way you don't have to use create and destroy  via NEW and DELETE.
You should avoid using new as much as possible, that way you limit the chances of having memory leaks.

If you use std::string instead of C-Style string, you also have the added advantage that you don't have to worry about what size you need to set your string length to.

The following is a modified version of your code using std::string, and the standard headers.

#pragma warning(disable : 4786) //For VC++ compiler
#include <cstdlib>

#include <iostream>
#include <fstream>
#include <string>
#include <vector>


using namespace std;
int main()
{
     vector<string>  ArrayOfStrings;
    // open file for reading and assign to array values
     ifstream file("c:\\boot.ini");

    if (! file.is_open())
    {
          cout << "Error opening file";
    }
    else
    {
          while (! file.eof())
          {
               string TempBuf;
               getline (file, TempBuf);
               cout << TempBuf << endl;
               ArrayOfStrings.push_back(TempBuf);
          }
    }
   
     system("pause");
    return 0;
}

0
 
jkrCommented:
>>Everything works fine except the "strcpy(name[index], buffer)" line.  
>>That line gives me a memory error

That is because you are copying to an array of uninitialize pointers. You have to allocate memory to hold the line, e.g.

         while (! file.eof())
         {
         
         file.getline (buffer, 100);
         cout << buffer << endl;
         name[index] = new char [ strlen ( buffer)]; // <--!!!
         strcpy(name[index], buffer);
         index++;

         
         }

However, you will have to 'delete[]' every entry when you are finished using them, or you will get memory leaks otherwise.
0
 
vadikCommented:
jkr right, but...
        name[index] = new char [ strlen ( buffer) + 1]; // <--!!!

Because strlen(s) = sizeof(s) - 1.
       
0
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
SidVicAuthor Commented:
OK, Axter, thanks for the portability advice.  In your example, how would you then refer to each member of the array (rather than "name[index]" that I planned to use)?  Thanks again.
0
 
Kyle AbrahamsSenior .Net DeveloperCommented:
you could use vectors as Axter suggested.  You refer to them just like arrays.  

IE: in his example: ArrayofStrings[0];

you could also, instead of doing char *:

you could do

string name[10];

then just use the = operator:

  getline(file, TempBuf);
  name[i] = TempBuf;
  i++;

in Axter's example however, he declares a new string every time his loop runs through.  (If I remember my initializations correctly)  Instead of doing that, you can use a clear function to get rid of the temporary string, and just re-use the same one.  (saves on memory, but costs in time.)
0
 
AxterCommented:
>>in Axter's example however, he declares a new string
>>every time his loop runs through.  (If I remember my
>>initializations correctly)  Instead of doing that, you
>>can use a clear function to get rid of the temporary
>>string, and just re-use the same one.  (saves on
>>memory, but costs in time.)

In most implementations memory would not be an issue, and the impact of the temporary variable would not be measurable.
This is due to the fact that most std::string implementations use reference counting.
This allows duplicate strings to share the same memory, and avoids unnecessary memory usage.
0
All Courses

From novice to tech pro — start learning today.