[source lang=cpp]
bool FileToArray(char *cFilename, int #, string *array)
{
fstream fa;
char ca[1024];
fa.open(cFilename,fstream::in);
if (!fa.is_open()) return false;
//count the number of lines in the
//file, and allocate enough strings to hold them
num = 0;
while (!fa.eof())
{
fa.getline(ca,sizeof(ca));
if (ca[0] == '#') continue; //don't count comment lines
if (strlen(ca) == 0) continue; //don't count blank lines
++num;
}
//allocate strings
array = new string[num];
if (array == NULL)
{
fa.close();
return false;
}
//return to the start of the file
fa.clear();
fa.seekg(0,fstream::beg);
//read the lines into the new allocated string array
int i = 0;
while (!fa.eof())
{
fa.getline(ca,sizeof(ca));
if (ca[0] == '#') continue; //don't count comment lines
if (strlen(ca) == 0) continue; //don't count blank lines
array = ca; ++i;
if (i >= num) break;
}
fa.close();
return true;
}
🔒 Locked
Pointer syntax
Advertisement
Original Post
This is driving me crazy. I've compiled and had my program crash every time. I am writing a small program which loads some lines from a file into an array of strings. Everything was working fine, but I've been adding different categories of strings, and different arrays, and I got tired of copying and pasting the code to load all the different arrays. So I decided to make the function below, so I could add string arrays and fill them as I pleased without rewritting the code again and replacing variable names every time I wanted another category. ie: int names = 0; string *name = NULL; int places = 0; string *place = NULL; ... ... FileToArray("names.txt",names,name); FileToArray("places.txt",places,place); ... ... This crashes to the point of having to use the task manager to kill the process, and then sometimes having to log back in to be able to compile a new copy of the .exe because windows still has it in use even after I kill it. So I've been messing around with the function argument list to try and fix this problem, and now I'm thinking I'll need **array for pointer to a pointer? But this gives me syntax errors on the lines where I try to access array array = new array = [wow] Hopefully I explained this good enough to not get 15 replies wondering what the hell I'm talking about [Edited by - Vampyre_Dark on April 14, 2006 6:45:53 PM]
By the way vampyre, you have a memory leak.
You are allocating new memory here but you don't delete the memory (that I can see).
array = new string[num];
I've upgraded from the hard crash to Process terminated with status 1 (0 minutes, 0 seconds) As soon as FileToArray() runs. Perhaps I don't need a pointer to pointer to access 'array'?
int names = 0; string* name = NULL;if (!FileToArray("names.txt",names,&name) ...bool FileToArray(char *cFilename, int #, string **array){ fstream fa; char ca[1024]; fa.open(cFilename,fstream::in); if (!fa.is_open()) return false; //count the number of lines in the //file, and allocate enough strings to hold them num = 0; while (!fa.eof()) { fa.getline(ca,sizeof(ca)); if (ca[0] == '#') continue; //don't count comment lines if (strlen(ca) == 0) continue; //don't count blank lines ++num; } //allocate strings and bail out //if there wasn't enough memory *array = new string[num]; if (*array == NULL) { fa.close(); return false; } //return to the start of the file fa.clear(); fa.seekg(0,fstream::beg); //read the lines into the new allocated string array int i = 0; while (!fa.eof()) { fa.getline(ca,sizeof(ca)); if (ca[0] == '#') continue; //don't count comment lines if (strlen(ca) == 0) continue; //don't count blank lines *array = ca; ++i; if (i >= num) break; } fa.close(); return true;}
If you're going to use C++, please, please, really use C++.
Much shorter, cleaner (free of details that get in the way of the meaningful abstractions), easier (no manual memory management - by the way, 'new' does NOT return null on failure, unless you tell it to; and it's been that way for years now - and only one pass through the file) and oh, it will actually work. :)
// Normally I don't preserve other people's whitespace etc. conventions// when posting here, but it's your lucky day I guess ;svector<string> names;if (!FileToArray("names.txt",names) ...bool FileToArray(const char *filename, vector<string>& names){ ifstream fa(filename); if (!fa.is_open()) return false; while (!fa.eof()) { string current; getline(fa, current); if (current.length() != 0 && current[0] != '#') { //don't count comment or blank lines names.push_back(name); } } return true; // fa is implicitly closed here by its destructor.}Much shorter, cleaner (free of details that get in the way of the meaningful abstractions), easier (no manual memory management - by the way, 'new' does NOT return null on failure, unless you tell it to; and it's been that way for years now - and only one pass through the file) and oh, it will actually work. :)
My guess is that you want to call
before
But i'm a bit rusty with working with C style arrays and strings, so I might be wrong
Anyways, here's a more C++ way to do it
given the filesomefile.txt containing:
it will output:
EDIT: took too long writing this and Zahlman beat me to it
if (strlen(ca) == 0) continue; //don't count blank linesbefore
if (ca[0] == '#') continue; //don't count comment linesBut i'm a bit rusty with working with C style arrays and strings, so I might be wrong
Anyways, here's a more C++ way to do it
#include <fstream>#include <string>#include <vector>#include <iostream>bool FileToArray(const std::string &cFilename, std::vector<std::string> &vec){ std::string line; std::ifstream fa( cFilename.c_str() ); if ( !fa.is_open() ) return false; while ( !fa.eof() ) { getline(fa, line); if ( line.empty() ) continue; if ( line[0] == '#') continue; // if you are reading a very large file the next line could potentially be slow // you could fix it by either knowing how many lines will be in the file and using // std::vector's reserve() method, or using another container instead, perhaps std::list vec.push_back(line); } // the ifstream will automatically close the file in it's destructor // and since it is about to go out of scope, the destructor is about to be called // it doesn't relate to this problem, but if a fstream already has an open file and you want to // open a different file you must .close() the stream before you open the next file return true;}int main (){ std::vector<std::string> foo; FileToArray("somefile.txt", foo); std::cout << "Num lines in vector: " << foo.size() << "\n\n"; std::cout << "Contents of vector:\n"; for (unsigned int i = 0; i < foo.size(); ++i) std::cout << "Line " << i << ": " << foo << "\n";}given the filesomefile.txt containing:
this is a test#commentfinalit will output:
Num lines in vector: 2Contents of vector:Line 0: this is a testLine 1: finalEDIT: took too long writing this and Zahlman beat me to it
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement