Use new to allocate memory and then delete the memory by using delete after the record is read..
if u post the code I can help you to correct it.
Main Topics
Browse All TopicsI'm writing a simple program to read up to 10,000 records from a text file (about 500kB). I didn't have any problem reading up to 5000 records but if I have more than that, the program gets terminated.
Does anybody have any idea to work around this? I'm using Visual C++. Thanks a lot for any help you can give.
This Question has been solved and asker verified All Experts Exchange premium technology solutions are available to subscription members.
Experts Exchange has been collecting answers to technology questions since 1996…3 million and counting! If you have a question, chances are we already have your answer.
If you can't find the exact answer you're looking for, ask our exclusive community of 50,000 experts. You’ll get a personalized answer from a trusted professional.
Thousands of free tech tips, tricks, how-to’s and tutorials are available in our peer reviewed articles section. See for yourself how smart our experts are, no login required.
Access the answers to your technology questions today.
30-day free trial. Register in 60 seconds.
Members of the expert community talk about why the experience at Experts Exchange is different than what you will find anywhere else.

Try it out and discover for yourself.
30-day free trial. Register in 60 seconds.
Join the community of experts here and help other tech pros by answering question in your area of expertise. You can earn FREE access to all Experts Exchange's premium features and resources.
>> the program gets terminated
Is there an access violation? Did you check with the debugger what happened?
You could make a try - catch block around, so you might get the error cause in the catch block. The code snippet from above looks fine - beside of the fact that outputting 10000 lines will last some time...
Regards, Alex
>> Visual C 1.5 to generate a DOS executable
Do you mean Visual C++ 1.5.2 to generate a Win 3.xx executable?
There wasn't a 640K limit in VC++ 1.x, but i remember that MFC CString allocated a minimum of 256 bytes (or more..) for any string. So 16 MB RAM wasn't enough to read 10000 CString objects from database...
Regards, Alex
MS DOS has (can we say had?) 640K of addressable conventional memory. A pointer could conveniently be used to address any 64K within that space but you would need to do clever things with far pointer arithmetic to address > 64K (recall huge pointers and pointer normalisation on far pointers... shudder). If you needed to address more than 640K, you needed to do clever things with extended or expanded memory. I'm not really up with version numbers of Microsoft C (I was a Turbo C fan back in those days), but I *think* that Microsoft's Visual C version 1 compilers were for DOS and Windows 3.x only. If you run a DOS executable on a Win32 platform, it runs in 8086 emulation, which means that you are back in the bad old days of 640K. I had no idea that they had things like CString back in those days. I expect the internal storage was in Cuniform :-)
//main.cpp
#include <stdio.h>
#include <string>
#include <fstream>
#include <iostream>
#include "record.h"
using namespace std;
string prefix;
string firstName;
string MiddleInit;
string lastName;
string title;
string company;
string department;
string address;
string city;
string state;
string zip1;
string zip2;
Record *record;
bool ReadFile(string Infilename, string Outfilename)
{
ifstream filein;
ofstream fileout;
string temp;
int pos;
filein.open(Infilename.c_s
fileout.open (Outfilename.c_str (), ios::out);
if ( filein.fail() )
{
cout << "Cannot open file to read." << endl;
return false;
}
if ( fileout.fail() )
{
cout << "Cannot open file to save." << endl;
return false;
}
int size = 0;
while (!filein.eof() && size < 5000) //if I take out the size < 5000 or put in a number > 5000, the program got terminated with an error
{
getline(filein, temp);
pos = temp.find (",", 0);
temp.erase (0, pos + 1);
pos = temp.find (",", 0);
prefix = temp.substr (1, pos - 2);
temp.erase (0, pos + 1);
pos = temp.find (",", 0);
firstName = temp.substr (1, pos - 2);
temp.erase (0, pos + 1);
pos = temp.find (",", 0);
MiddleInit = temp.substr (1, pos - 2);
temp.erase (0, pos + 1);
pos = temp.find (",", 0);
lastName = temp.substr (1, pos - 2);
temp.erase (0, pos + 1);
pos = temp.find (",", 0);
temp.erase (0, pos + 1);
pos = temp.find (",", 0);
title = temp.substr (1, pos - 2);
temp.erase (0, pos + 1);
pos = temp.find (",", 0);
company = temp.substr (1, pos - 2);
temp.erase (0, pos + 1);
pos = temp.find (",", 0);
department = temp.substr (1, pos - 2);
temp.erase (0, pos + 1);
pos = temp.find (",", 0);
address = temp.substr (1, pos - 2);
temp.erase (0, pos + 1);
pos = temp.find (",", 0);
city = temp.substr (1, pos - 2);
temp.erase (0, pos + 1);
pos = temp.find (",", 0);
state = temp.substr (1, pos - 2);
temp.erase (0, pos + 1);
pos = temp.find (",", 0);
zip1 = temp.substr (1, pos - 2);
temp.erase (0, pos + 1);
pos = temp.find (",", 0);
zip2 = temp.substr (1, pos - 2);
record = new Record(prefix, firstName, MiddleInit, lastName, title, company, department, address, city, state, zip1, zip2);
fileout << record->getPrefix() << " " << record->getfirstName() << " " << record->getMiddleInit() << " " << record->getlastName() << endl;
if (record->getTitle() !="")
fileout << record->getTitle() << endl;
fileout << record->getCompany() << endl;
if (record->getDept() !="")
fileout << record->getDept() << endl;
fileout << record->getAdd() << endl;
fileout << record->getCity() << " " << record->getState() << " " << record->getZip1() << "-" << record->getZip2() << endl << endl;
size++;
delete record;
}
}
void main()
{
string Infilename, Outfilename;
cout << "Enter a file name to read: ";
cin >> Infilename;
cout << "Enter a file name to save: ";
cin >> Outfilename;
bool success = ReadFile (Infilename, Outfilename);
}
//record.h
#include <stdio.h>
#include <string>
#include <iostream>
using namespace std;
class Record
{
private:
string prefix;
string firstName;
string MiddleInit;
string lastName;
string title;
string company;
string department;
string address;
string city;
string state;
string zip1;
string zip2;
public:
Record( const string str1 = "", const string str2 ="" , const string str3 ="", const string str4 ="", const string str5 ="", const string str6="", const string str7="", const string str8="", const string str9="", const string str10="", const string str11="", const string str12="")
{
prefix = str1;
firstName = str2;
MiddleInit = str3;
lastName = str4;
title = str5;
company = str6;
department = str7;
address = str8;
city = str9;
state = str10;
zip1 = str11;
zip2 = str12;
}
set( const string str1, const string str2, const string str3, const string str4, const string str5, const string str6, const string str7, const string str8, const string str9, const string str10, const string str11, const string str12)
{
prefix = str1;
firstName = str2;
MiddleInit = str3;
lastName = str4;
title = str5;
company = str6;
department = str7;
address = str8;
city = str9;
state = str10;
zip1 = str11;
zip2 = str12;
}
string getPrefix()
{
return prefix;
}
string getfirstName()
{
return firstName;
}
string getMiddleInit()
{
return MiddleInit;
}
string getlastName()
{
return lastName;
}
string getTitle()
{
return title;
}
string getCompany()
{
return company;
}
string getDept()
{
return department;
}
string getAdd()
{
return address;
}
string getCity()
{
return city;
}
string getState()
{
return state;
}
string getZip1()
{
return zip1;
}
string getZip2()
{
return zip2;
}
};
This is how the input file looks like. It has a few thousands lines like this. I don't know how the users get this file, but this will be the input to my program.
"00000001","MS","D","L","G
"01759019","MR","RICH","",
My error says "abnormal program termination". If I hit "Retry" then the outputs still come out correctly. But I would lile to have the users not see this error. Is there any way you know of, please?
Thank you very much for your help.
Meanwhile try this:
Replace your record.cpp with this one. Let me know how it goes.
//main.cpp
#include <stdio.h>
#include <string>
#include <fstream>
#include <iostream>
#include "record.h"
using namespace std;
string prefix;
string firstName;
string MiddleInit;
string lastName;
string title;
string company;
string department;
string address;
string city;
string state;
string zip1;
string zip2;
Record *record=NULL;
void clearIT(void){
prefix.erase();
firstName.erase();
MiddleInit.erase();
lastName.erase();
title.erase();
company.erase();
department.erase();
address.erase();
city.erase();
state.erase();
zip1.erase();
zip2.erase();
}
bool ReadFile(string Infilename, string Outfilename)
{
ifstream filein;
ofstream fileout;
string temp="";
int pos=0;
filein.open(Infilename.c_s
fileout.open (Outfilename.c_str (), ios::out);
if ( filein.fail() )
{
cout << "Cannot open file to read." << endl;
return false;
}
if ( fileout.fail() )
{
cout << "Cannot open file to save." << endl;
return false;
}
int size = 0;
while (!filein.eof() )
{
clearIT();
getline(filein, temp);
pos = temp.find (",", 0);
temp.erase (0, pos + 1);
pos = temp.find (",", 0);
if(pos>2){
prefix = temp.substr (1, pos - 2);
temp.erase (0, pos + 1);
pos = temp.find (",", 0);
firstName = temp.substr (1, pos - 2);
temp.erase (0, pos + 1);
pos = temp.find (",", 0);
MiddleInit = temp.substr (1, pos - 2);
temp.erase (0, pos + 1);
pos = temp.find (",", 0);
lastName = temp.substr (1, pos - 2);
temp.erase (0, pos + 1);
pos = temp.find (",", 0);
temp.erase (0, pos + 1);
pos = temp.find (",", 0);
title = temp.substr (1, pos - 2);
temp.erase (0, pos + 1);
pos = temp.find (",", 0);
company = temp.substr (1, pos - 2);
temp.erase (0, pos + 1);
pos = temp.find (",", 0);
department = temp.substr (1, pos - 2);
temp.erase (0, pos + 1);
pos = temp.find (",", 0);
address = temp.substr (1, pos - 2);
temp.erase (0, pos + 1);
pos = temp.find (",", 0);
city = temp.substr (1, pos - 2);
temp.erase (0, pos + 1);
pos = temp.find (",", 0);
state = temp.substr (1, pos - 2);
temp.erase (0, pos + 1);
pos = temp.find (",", 0);
zip1 = temp.substr (1, pos - 2);
temp.erase (0, pos + 1);
pos = temp.find (",", 0);
zip2 = temp.substr (1, pos - 2);
}
record = new Record(prefix, firstName, MiddleInit, lastName, title, company, department, address, city, state, zip1, zip2);
fileout << record->getPrefix() << " " << record->getfirstName() << " " << record->getMiddleInit() << " " << record->getlastName() << endl;
if (record->getTitle() !="")
fileout << record->getTitle() << endl;
fileout << record->getCompany() << endl;
if (record->getDept() !="")
fileout << record->getDept() << endl;
fileout << record->getAdd() << endl;
fileout << record->getCity() << " " << record->getState() << " " << record->getZip1() << "-" << record->getZip2() << endl << endl;
size++;
if(record){
delete record;
record=NULL;
}
temp.erase();
}
}
void main()
{
string Infilename, Outfilename;
cout << "Enter a file name to read: ";
cin >> Infilename;
cout << "Enter a file name to save: ";
cin >> Outfilename;
bool success = ReadFile (Infilename, Outfilename);
}
while (!filein.eof() )
{
getline(filein, temp);
That sequence looks wrong as you don't check getline error. At end-of-file the last call to getline() most probably fails, what sets the stream status to fail and not to eof. The condition size < 5000 simply prevents your prog from reaching file end.
I would suggest to try that:
while (!getline(filein, temp))
{
...
Regards, Alex
>> I had no idea that they had things like CString back in those days.
I started with 16 Bit VC++ 1.3 and MFC 1.0 in 1993. The platform was Windows 3.11. The difference to Borland C++ was that VC++ had an integrated 'visual' Resource Editor - called ApStudio and MFC with Scribble Tutorial.. ODBC Access came with VC 1.4 in spring 1994 (CRecordset class and jet engine driver for Access 1.1). DOS applications could be compiled using a DOS-Extender (i forgot the name as i had no DOS past but came from VMS).
There was a Bit VC 1.1 (same time as 16 Bit 1.3) for Windows NT 3.5 (that had a Win 3.11 GUI).
Regards, Alex
<Apologies for the continued trip down memory lane...>
DOS extenders like Phar Lap were only needed to extend the capabilities of DOS to break through the 640K barrier. I did pitifully little Windows 3.x stuff with Borland's OWL (Object Windows Library). Borland didn't seem to license much off Microsoft... possibly only the resource compiler. But most of my development at that time was text mode, compiled with a 1989 copy of Turbo C 1.0. which could fit onto a bootable 720K floppy with enough space for pkzip and a text editor but which wasn't to be trusted with floating point.
<Returning to the current decade... and the thread>
I think you're right about getline or perhaps an insufficient number of commas in an errant record making npos == string::npos, which isn't tested for. It certainly isn't a DOS thing :-)
Business Accounts
Answer for Membership
by: OnegaZhangPosted on 2004-11-03 at 20:18:26ID: 12489975
It should work. protect your code by checking the data readed, if it is an empty line? Is every field valid?