M
muser
In the following function there is an access violation error, some
memory can't be read. A week ago this code did compile.
Can anyone possibly tell me why my compiler is unable to read part of
this function.
bool processdrecord( ofstream& prnfile, ofstream& validdata, char*
record )
{
drecord Newdrecord;
char customercode[5];
strncpy( customercode, &record[1], 5);
customercode[5] = '\0';
if(!CheckAllNumeric( customercode )){
prnfile<< "Invalid: D record customer code does not contain
numerical format"<<endl;
prnfile<< record <<endl;
return false;
}
Newdrecord.customercode[5] = atol( customercode );
validdata.write((char*) record, Newdrecord.customercode[5]);
return true;
}
the program in full.
#include <iostream>
#include <iomanip>
#include <fstream>
#include <cstring>
#include <cstdlib>
using namespace std;
struct crecord {
long customercode[5];
char customername[21];
char customeraddress[61];
double customerbalance;
double creditlimit;
};
crecord Newcrecord;
struct irrecord {
long customercode[5];
long partnum[5];
long issue_rec;
};
irrecord Newirrecord;
struct drecord {
long customercode[5];
};
drecord Newdrecord;
////////////////////////////////////////////////////////////
bool IRRecordvalidlength(char* record)
{
int len;
switch(record[0])
{
case'i':
case'I':
case'r':
case'R':
len= strlen(record);
if(len<17)
return false;
break;
}
return true;
};
////////////////////////////////////////////////////////////
bool CRecordvalidlength(char* record)
{
int len;
switch(record[0])
{
case'c':
case'C':
len = strlen(record);
if(len<103)
return false;
break;
}
return true;
}
////////////////////////////////////////////////////////
bool Drecordvalidlength( char* record )
{
int len;
switch(record[0])
{
case'd':
case'D':
len = strlen(record);
if(len<7)
return false;
break;
}
return true;
}
////////////////////////////////////////////////////////////////////////////
bool CheckAllNumeric( const char * string )
{
int Len = strlen( string );
for( int i = 0; i < Len; ++i )
if( !isdigit( string ) )
return false;
return true;
}
////////////////////////////////////////////////////////////////////////////
bool CheckFloatNumber( const char* string )
{
int Len = strlen( string );
for( int i = 0; i < Len; ++i )
if( !isdigit( string ) &&
string != '.' )
return false;
return true;
}
///////////////////////////////////////////////////////////////////////////
irrecord* CheckDigit(ofstream& prnfile, ofstream& validdata, char*
record )
{
char code[5];
int weightingfactor = 5;
int checkdigit;
int remainder;
int check1;
strncpy(code, &record[2], 6);
code[5] = '\0';
Newirrecord.customercode[5] = atol( code );
for(int i =0; i < 6; ++i)
check1 += Newirrecord.customercode * weightingfactor;
weightingfactor --;
remainder = check1 % 11;
checkdigit = 11 - remainder;
if(! Newirrecord.customercode[5] == checkdigit){
prnfile<< "Invalid customer number";
prnfile<< record << endl;
}
return false;
if(Newirrecord.customercode[5] == checkdigit){
validdata.write((char*) record, Newirrecord.customercode[5]);
}
}
/////////////////////////////////////////////////////////////////////////////////////
drecord* checkdigit(ofstream& prnfile, ofstream& validdata, char*
record )
{
char code[5];
int weightingfactor = 5;
int checkdigit;
int remainder;
int check1;
strncpy(code, &record[2], 5);
code[5] = '\0';
Newdrecord.customercode[5] = atol( code );
for(int i =0; i < 6; ++i)
check1 += Newdrecord.customercode * weightingfactor;
weightingfactor --;
remainder = check1 % 11;
checkdigit = 11 - remainder;
if(! Newdrecord.customercode[5] == checkdigit){
prnfile<< "Invalid customer number";
prnfile<< record << endl;
}
return false;
validdata.write((char*) record, Newdrecord.customercode[5]);
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
crecord* checkdigitforcustomercode( ofstream& prnfile, ofstream&
validdata, char* record )
{
char code[5];
int weightingfactor = 5;
int checkdigit;
int remainder;
int check1;
strncpy(code, &record[2], 5);
code[5] = '\0';
Newcrecord.customercode[5] = atol( code );
for(int i =0; i < 6; ++i)
check1 += Newcrecord.customercode * weightingfactor;
weightingfactor --;
remainder = check1 % 11;
checkdigit = 11 - remainder;
if(checkdigit == 11){
checkdigit = 'X';
}
else
if(checkdigit = checkdigit = 10){
checkdigit = '0';
}
if(! Newcrecord.customercode[5] == checkdigit){
prnfile<< "Invalid customer number";
prnfile<< record << endl;
}
return false;
validdata.write((char*) record, Newcrecord.customercode[5]);
}
////////////////////////////////////////////////////////////////////////////////////
irrecord* checkdigitforpartnum(ofstream& prnfile, ofstream& validdata,
char* record)
{
int weightingfactor2;
char part_num[6];
int partnumcheck;
int produce;
int holdall;
strncpy(part_num, &record[7], 6);
part_num[6] = '\0';
Newirrecord.partnum[6] = atol( part_num );
weightingfactor2 = 6;
for(int i=0; i < 6; ++i)
holdall += Newirrecord.partnum * weightingfactor2;
weightingfactor2 --;
produce = holdall % 11;
partnumcheck = 11 - produce;
if(partnumcheck == 11){
partnumcheck = 'X';
}
else
if(partnumcheck = 10){
partnumcheck = '0';
}
if(! Newirrecord.partnum[5] == partnumcheck){
prnfile<< "Invalid: Incorrect part number, check digit invalid";
prnfile<< record << endl;
}
return false;
validdata.write((char*) record, Newirrecord.partnum[5]);
}
////////////////////////////////////////////////////////////////////////////////////
bool CheckAddress( const char* alpha )
{
int max_alpha = 60;
for( int i = 0; i < max_alpha; ++i )
if( !isalpha( alpha ) && ( alpha != ';;;;' ) && ( alpha !=
' ' ))
if(Newcrecord.customeraddress[61] != (alpha))
return false;
return true;
}
///////////////////////////////////////////////////////////////////////////////
bool Processcrecord( ofstream& prnfile, ofstream& validdata, char*
record )
{
char customercode[6];
char balance[10];
char limit[10];
crecord Newcrecord;
//
// process the customer code
//
strncpy( customercode, &record[1], 5 );
customercode[5] = '\0';
if( !CheckAllNumeric( customercode ) ) {
prnfile << "Invalid: customer code needs to be all numeric
[position 3 - 5 characters]:\n";
prnfile << record << endl;
return false;
}
Newcrecord.customercode[5] = atol( customercode );
//
// process the customer name
//
strncpy( Newcrecord.customername, &record[7], 20 );
Newcrecord.customername[20] = '\0';
//
// process the customer address
//
strncpy( Newcrecord.customeraddress, &record[27], 61 );
Newcrecord.customeraddress[61] = '\0';
// process the customer balance
//
strncpy( balance, &record[87], 9 );
balance[9] = '\0';
if( !CheckFloatNumber( balance ) ) {
prnfile << "Invalid: balance field is not a valid number [position
88 - 9 characters]:\n";
prnfile << record << endl;
return false;
}
Newcrecord.customerbalance = atof( balance );
cout << setiosflags(ios::fixed)
<< setprecision(2);
validdata.write((char*) record, Newcrecord.customerbalance );
//
// process the customer limit
//
strncpy( limit, &record[97], 9 );
limit[9] = '\0';
if( !CheckFloatNumber( limit ) ) {
prnfile << "Invalid: limit field is not a valid number [position
98 - 9 characters]:\n";
prnfile << record << endl;
return false;
}
Newcrecord.creditlimit = atof( limit );
validdata.write((char*) record, Newcrecord.creditlimit );
return true;
}
///////////////////////////////////////////////////////
bool processdrecord( ofstream& prnfile, ofstream& validdata, char*
record )
{
drecord Newdrecord;
char customercode[5];
strncpy( customercode, &record[1], 5);
customercode[5] = '\0';
if(!CheckAllNumeric( customercode )){
prnfile<< "Invalid: D record customer code does not contain
numerical format"<<endl;
prnfile<< record <<endl;
return false;
}
Newdrecord.customercode[5] = atol( customercode );
validdata.write((char*) record, Newdrecord.customercode[5]);
return true;
}
/////////////////////////////////////////////////////////////////////////
bool ProcessIRecord( ofstream& prnfile, ofstream& validdata, char*
record )
{
char customer[6];
char issue_rec[5];
char code[4];
char part[6];
long customer_code;
long issuerec;
long partnum[6];
//
// process the customer code
//
strncpy( customer, &record[2], 5 );
customer[6] = '\0';
if( !CheckAllNumeric( customer ) ) {
prnfile << "Invalid: customer code needs to be all numeric
[position 3 - 5 characters]:\n";
prnfile << record << endl;
return false;
}
customer_code = atol( customer );
//
// process the part number
//
strncpy( part, &record[7], 6 );
part[6] = '\0';
if( !CheckAllNumeric( part ) ) {
prnfile << "Invalid: part number needs to be all numeric [position
9 - 6 characters]:\n";
prnfile << record << endl;
return false;
}
partnum[6] = atol( part );
validdata.write((char*) record, partnum[6]);
return true;
//
// process the third number
//
strncpy( issue_rec, &record[13], 4 );
code[4] = '\0';
if( !CheckAllNumeric( issue_rec ) ) {
prnfile << "Invalid: the code needs to be all numeric [position 16
- 4 characters]:\n";
prnfile << record << endl;
return false;
}
issuerec = atol( issue_rec );
return true;
}
/////////////////////////////////////////////////////////////////////////
int main()
{
const char infile[] = "A:\\514650TD.txt";
const char outfile[] = "A:\\514650VD.DAT";
const char printerfile[] = "A:\\514650.TXT";
int max = 256;
char temp1[256];
ifstream testdata;
ofstream validdata;
ofstream prnfile;
testdata.open("A:\\514650TD.txt", ios::in);
if(!testdata)
{
cout<<"The file does not already exist" << infile << endl;
return EXIT_FAILURE;
}
validdata.open("A:\\514650.DAT", ios:ut | ios::binary);
if(!validdata.is_open())
{
cout<<" The file could not be opened " << outfile <<endl;
return EXIT_FAILURE;
}
prnfile.open("A:\\514650.TXT", ios:ut);
if(!prnfile)
{
cout<< "File could not be opened" << prnfile << endl;
return EXIT_FAILURE;
};
prnfile << "C_RECORD, I-R RECORD, D_RECORD ERRORS" << endl;
while( testdata.getline( temp1, sizeof(temp1)) ){
if(!CRecordvalidlength( temp1 )){
prnfile<<"Invalid: record does not contain enough characters:\n";
prnfile<< temp1 <<endl;
continue;
}
if(!IRRecordvalidlength( temp1 )){
prnfile<< "Invalid: record does not contain enough characters:\n";
prnfile<< temp1 << endl;
continue;
}
if(!Drecordvalidlength( temp1 )){
prnfile<< "Invalid: record does not contain enough characters:\n";
prnfile<< temp1 << endl;
continue;
};
switch( temp1[0] )
{
case 'c':
case 'C':
Processcrecord( prnfile, validdata, temp1 );
checkdigitforcustomercode( prnfile, validdata, temp1);
//must be able to reference
//these two, but only by creating variables within the function
they came from.
//it could be possible that these variables will have to be
pointers.
//there is a page about it in the newsgroups.
break;
case 'i':
case 'I':
case 'r':
case 'R':
ProcessIRecord( prnfile, validdata, temp1 );
CheckDigit( prnfile, validdata, temp1 );
checkdigitforpartnum( prnfile, validdata, temp1 );
break;
case 'd':
case 'D':
processdrecord( prnfile, validdata, temp1 );
checkdigit( prnfile, validdata, temp1 );
break;
default: prnfile<< "Unknown record";
prnfile<< temp1 << endl;
};
}
testdata.close();
validdata.close();
prnfile.close();
return EXIT_SUCCESS;
};
memory can't be read. A week ago this code did compile.
Can anyone possibly tell me why my compiler is unable to read part of
this function.
bool processdrecord( ofstream& prnfile, ofstream& validdata, char*
record )
{
drecord Newdrecord;
char customercode[5];
strncpy( customercode, &record[1], 5);
customercode[5] = '\0';
if(!CheckAllNumeric( customercode )){
prnfile<< "Invalid: D record customer code does not contain
numerical format"<<endl;
prnfile<< record <<endl;
return false;
}
Newdrecord.customercode[5] = atol( customercode );
validdata.write((char*) record, Newdrecord.customercode[5]);
return true;
}
the program in full.
#include <iostream>
#include <iomanip>
#include <fstream>
#include <cstring>
#include <cstdlib>
using namespace std;
struct crecord {
long customercode[5];
char customername[21];
char customeraddress[61];
double customerbalance;
double creditlimit;
};
crecord Newcrecord;
struct irrecord {
long customercode[5];
long partnum[5];
long issue_rec;
};
irrecord Newirrecord;
struct drecord {
long customercode[5];
};
drecord Newdrecord;
////////////////////////////////////////////////////////////
bool IRRecordvalidlength(char* record)
{
int len;
switch(record[0])
{
case'i':
case'I':
case'r':
case'R':
len= strlen(record);
if(len<17)
return false;
break;
}
return true;
};
////////////////////////////////////////////////////////////
bool CRecordvalidlength(char* record)
{
int len;
switch(record[0])
{
case'c':
case'C':
len = strlen(record);
if(len<103)
return false;
break;
}
return true;
}
////////////////////////////////////////////////////////
bool Drecordvalidlength( char* record )
{
int len;
switch(record[0])
{
case'd':
case'D':
len = strlen(record);
if(len<7)
return false;
break;
}
return true;
}
////////////////////////////////////////////////////////////////////////////
bool CheckAllNumeric( const char * string )
{
int Len = strlen( string );
for( int i = 0; i < Len; ++i )
if( !isdigit( string ) )
return false;
return true;
}
////////////////////////////////////////////////////////////////////////////
bool CheckFloatNumber( const char* string )
{
int Len = strlen( string );
for( int i = 0; i < Len; ++i )
if( !isdigit( string ) &&
string != '.' )
return false;
return true;
}
///////////////////////////////////////////////////////////////////////////
irrecord* CheckDigit(ofstream& prnfile, ofstream& validdata, char*
record )
{
char code[5];
int weightingfactor = 5;
int checkdigit;
int remainder;
int check1;
strncpy(code, &record[2], 6);
code[5] = '\0';
Newirrecord.customercode[5] = atol( code );
for(int i =0; i < 6; ++i)
check1 += Newirrecord.customercode * weightingfactor;
weightingfactor --;
remainder = check1 % 11;
checkdigit = 11 - remainder;
if(! Newirrecord.customercode[5] == checkdigit){
prnfile<< "Invalid customer number";
prnfile<< record << endl;
}
return false;
if(Newirrecord.customercode[5] == checkdigit){
validdata.write((char*) record, Newirrecord.customercode[5]);
}
}
/////////////////////////////////////////////////////////////////////////////////////
drecord* checkdigit(ofstream& prnfile, ofstream& validdata, char*
record )
{
char code[5];
int weightingfactor = 5;
int checkdigit;
int remainder;
int check1;
strncpy(code, &record[2], 5);
code[5] = '\0';
Newdrecord.customercode[5] = atol( code );
for(int i =0; i < 6; ++i)
check1 += Newdrecord.customercode * weightingfactor;
weightingfactor --;
remainder = check1 % 11;
checkdigit = 11 - remainder;
if(! Newdrecord.customercode[5] == checkdigit){
prnfile<< "Invalid customer number";
prnfile<< record << endl;
}
return false;
validdata.write((char*) record, Newdrecord.customercode[5]);
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
crecord* checkdigitforcustomercode( ofstream& prnfile, ofstream&
validdata, char* record )
{
char code[5];
int weightingfactor = 5;
int checkdigit;
int remainder;
int check1;
strncpy(code, &record[2], 5);
code[5] = '\0';
Newcrecord.customercode[5] = atol( code );
for(int i =0; i < 6; ++i)
check1 += Newcrecord.customercode * weightingfactor;
weightingfactor --;
remainder = check1 % 11;
checkdigit = 11 - remainder;
if(checkdigit == 11){
checkdigit = 'X';
}
else
if(checkdigit = checkdigit = 10){
checkdigit = '0';
}
if(! Newcrecord.customercode[5] == checkdigit){
prnfile<< "Invalid customer number";
prnfile<< record << endl;
}
return false;
validdata.write((char*) record, Newcrecord.customercode[5]);
}
////////////////////////////////////////////////////////////////////////////////////
irrecord* checkdigitforpartnum(ofstream& prnfile, ofstream& validdata,
char* record)
{
int weightingfactor2;
char part_num[6];
int partnumcheck;
int produce;
int holdall;
strncpy(part_num, &record[7], 6);
part_num[6] = '\0';
Newirrecord.partnum[6] = atol( part_num );
weightingfactor2 = 6;
for(int i=0; i < 6; ++i)
holdall += Newirrecord.partnum * weightingfactor2;
weightingfactor2 --;
produce = holdall % 11;
partnumcheck = 11 - produce;
if(partnumcheck == 11){
partnumcheck = 'X';
}
else
if(partnumcheck = 10){
partnumcheck = '0';
}
if(! Newirrecord.partnum[5] == partnumcheck){
prnfile<< "Invalid: Incorrect part number, check digit invalid";
prnfile<< record << endl;
}
return false;
validdata.write((char*) record, Newirrecord.partnum[5]);
}
////////////////////////////////////////////////////////////////////////////////////
bool CheckAddress( const char* alpha )
{
int max_alpha = 60;
for( int i = 0; i < max_alpha; ++i )
if( !isalpha( alpha ) && ( alpha != ';;;;' ) && ( alpha !=
' ' ))
if(Newcrecord.customeraddress[61] != (alpha))
return false;
return true;
}
///////////////////////////////////////////////////////////////////////////////
bool Processcrecord( ofstream& prnfile, ofstream& validdata, char*
record )
{
char customercode[6];
char balance[10];
char limit[10];
crecord Newcrecord;
//
// process the customer code
//
strncpy( customercode, &record[1], 5 );
customercode[5] = '\0';
if( !CheckAllNumeric( customercode ) ) {
prnfile << "Invalid: customer code needs to be all numeric
[position 3 - 5 characters]:\n";
prnfile << record << endl;
return false;
}
Newcrecord.customercode[5] = atol( customercode );
//
// process the customer name
//
strncpy( Newcrecord.customername, &record[7], 20 );
Newcrecord.customername[20] = '\0';
//
// process the customer address
//
strncpy( Newcrecord.customeraddress, &record[27], 61 );
Newcrecord.customeraddress[61] = '\0';
// process the customer balance
//
strncpy( balance, &record[87], 9 );
balance[9] = '\0';
if( !CheckFloatNumber( balance ) ) {
prnfile << "Invalid: balance field is not a valid number [position
88 - 9 characters]:\n";
prnfile << record << endl;
return false;
}
Newcrecord.customerbalance = atof( balance );
cout << setiosflags(ios::fixed)
<< setprecision(2);
validdata.write((char*) record, Newcrecord.customerbalance );
//
// process the customer limit
//
strncpy( limit, &record[97], 9 );
limit[9] = '\0';
if( !CheckFloatNumber( limit ) ) {
prnfile << "Invalid: limit field is not a valid number [position
98 - 9 characters]:\n";
prnfile << record << endl;
return false;
}
Newcrecord.creditlimit = atof( limit );
validdata.write((char*) record, Newcrecord.creditlimit );
return true;
}
///////////////////////////////////////////////////////
bool processdrecord( ofstream& prnfile, ofstream& validdata, char*
record )
{
drecord Newdrecord;
char customercode[5];
strncpy( customercode, &record[1], 5);
customercode[5] = '\0';
if(!CheckAllNumeric( customercode )){
prnfile<< "Invalid: D record customer code does not contain
numerical format"<<endl;
prnfile<< record <<endl;
return false;
}
Newdrecord.customercode[5] = atol( customercode );
validdata.write((char*) record, Newdrecord.customercode[5]);
return true;
}
/////////////////////////////////////////////////////////////////////////
bool ProcessIRecord( ofstream& prnfile, ofstream& validdata, char*
record )
{
char customer[6];
char issue_rec[5];
char code[4];
char part[6];
long customer_code;
long issuerec;
long partnum[6];
//
// process the customer code
//
strncpy( customer, &record[2], 5 );
customer[6] = '\0';
if( !CheckAllNumeric( customer ) ) {
prnfile << "Invalid: customer code needs to be all numeric
[position 3 - 5 characters]:\n";
prnfile << record << endl;
return false;
}
customer_code = atol( customer );
//
// process the part number
//
strncpy( part, &record[7], 6 );
part[6] = '\0';
if( !CheckAllNumeric( part ) ) {
prnfile << "Invalid: part number needs to be all numeric [position
9 - 6 characters]:\n";
prnfile << record << endl;
return false;
}
partnum[6] = atol( part );
validdata.write((char*) record, partnum[6]);
return true;
//
// process the third number
//
strncpy( issue_rec, &record[13], 4 );
code[4] = '\0';
if( !CheckAllNumeric( issue_rec ) ) {
prnfile << "Invalid: the code needs to be all numeric [position 16
- 4 characters]:\n";
prnfile << record << endl;
return false;
}
issuerec = atol( issue_rec );
return true;
}
/////////////////////////////////////////////////////////////////////////
int main()
{
const char infile[] = "A:\\514650TD.txt";
const char outfile[] = "A:\\514650VD.DAT";
const char printerfile[] = "A:\\514650.TXT";
int max = 256;
char temp1[256];
ifstream testdata;
ofstream validdata;
ofstream prnfile;
testdata.open("A:\\514650TD.txt", ios::in);
if(!testdata)
{
cout<<"The file does not already exist" << infile << endl;
return EXIT_FAILURE;
}
validdata.open("A:\\514650.DAT", ios:ut | ios::binary);
if(!validdata.is_open())
{
cout<<" The file could not be opened " << outfile <<endl;
return EXIT_FAILURE;
}
prnfile.open("A:\\514650.TXT", ios:ut);
if(!prnfile)
{
cout<< "File could not be opened" << prnfile << endl;
return EXIT_FAILURE;
};
prnfile << "C_RECORD, I-R RECORD, D_RECORD ERRORS" << endl;
while( testdata.getline( temp1, sizeof(temp1)) ){
if(!CRecordvalidlength( temp1 )){
prnfile<<"Invalid: record does not contain enough characters:\n";
prnfile<< temp1 <<endl;
continue;
}
if(!IRRecordvalidlength( temp1 )){
prnfile<< "Invalid: record does not contain enough characters:\n";
prnfile<< temp1 << endl;
continue;
}
if(!Drecordvalidlength( temp1 )){
prnfile<< "Invalid: record does not contain enough characters:\n";
prnfile<< temp1 << endl;
continue;
};
switch( temp1[0] )
{
case 'c':
case 'C':
Processcrecord( prnfile, validdata, temp1 );
checkdigitforcustomercode( prnfile, validdata, temp1);
//must be able to reference
//these two, but only by creating variables within the function
they came from.
//it could be possible that these variables will have to be
pointers.
//there is a page about it in the newsgroups.
break;
case 'i':
case 'I':
case 'r':
case 'R':
ProcessIRecord( prnfile, validdata, temp1 );
CheckDigit( prnfile, validdata, temp1 );
checkdigitforpartnum( prnfile, validdata, temp1 );
break;
case 'd':
case 'D':
processdrecord( prnfile, validdata, temp1 );
checkdigit( prnfile, validdata, temp1 );
break;
default: prnfile<< "Unknown record";
prnfile<< temp1 << endl;
};
}
testdata.close();
validdata.close();
prnfile.close();
return EXIT_SUCCESS;
};