473,719 Members | 2,064 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Abnormal program termination - Please help!

Hello,

I have written a program that reads three types of records, validates
them acording to certain requirements and writes the valid records
into a binary file. The invalid records are supposed to be reported on
the printer but I have commented those pieces of code and have got
those records printed on the screen. I am using Microsoft Visual C++
6.0 on Microsoft XP (Home) platform.

I am facing some problems in getting desire results:

1. My program runs with some abnormal termination at the very end
(which is the return 0; line at the end of mymain.cpp).

2.The output saved in the validated file mydataVF.dat is also consists
of characters beyond my expectation.

3. In the function validate_writeC (...), you will find the strings as
local variables spread among various lines in function header. I have
done so, because my program overwrites or "loses" certain strings in
this function if I define all those strings in one line like:

char s1[6], s2[21], s3[61], s4[10], s5[8];

Does this happen because the memory locations for these strings are
contiguous and my program tends to overwrite some of the important
data? Does this have something to do with the size of local variables
for a function? How can I remedy these problems?

Grateful for help,
Mahmood Ahmad

[FILE: myheaderfileP1. h]

#include <iostream>

using std::cout;
using std::endl;
using std::ios;

#include <string>

using std::string;

#include <fstream>

using std::ifstream;
using std::ofstream;

#include <iomanip>

using std::setprecisi on;
using std::setiosflag s;
using std::resetiosfl ags;
using std::setw;

#include <cstdlib>
#include <ctype.h>
//
#define DEBUG
//
typedef struct {
char rec_type;
char cust_code[6];
char part_num[7];
char quantity[5];
} IREC;
//
typedef struct {
char rec_type;
char cust_code[6];
} DREC;
//
typedef struct {
char rec_type;
char cust_code[6];
char cust_name[21];
char cust_add[61];
char cust_balance[10];
char credit_lim[8];
} CREC;
//
#define MAXCHARS 150
#define MINRECORDS 100
#define IREC_SIZE sizeof(IREC)
#define CREC_SIZE sizeof(CREC)
#define DREC_SIZE sizeof(DREC)
//
ifstream trans_file;
ofstream valid_file, prn_file;
//
int nirec = 0;
int ncrec = 0;
int ndrec = 0;
//
int temp, valid_count = 0;
int prn_count = 0;
int total_count = 0;
char valid_char1, valid_char2;
//
bool validate_writeI (char* txtrec);
bool validate_writeC (char* txtrec);
bool validate_writeD (char* txtrec);
//
bool validate_writeI (char* txtrec)
{
bool validation_flag = true;
int rem, sum = 0;
int num_wt[4] = {5, 4, 3, 2};
int part_wt[5] = {6, 5, 4, 3, 2};
IREC irec;
char mych;
char s1[6], s2[7], s3[5];
//
for(int i=1; i<sizeof(IREC) ; i++)
{
mych = txtrec[i];
if(i <= 5)
s1[i-1] = mych;
else if((i > 5) && (i <= 11))
s2[i-6] = mych;
else
s3[i-12] = mych;
}
s1[5] = '\0';
s2[6] = '\0';
s3[4] = '\0';
for(i=1; i<5; i++)
{
mych = txtrec[i];
if(!isdigit(myc h))
{
validation_flag = false; // print with reason to printer
/* prn_file << (total_count+1) << "\t\t"
<< "Record Type = " << txtrec[0] << endl << "\t\t"
<< "Customer code = " << s1 << " - Invalid characters."
<< endl << "\t\t"
<< "Part Number = " << s2 << endl << "\t\t"
<< "Quantity = " << s3 << endl << endl;*/
#ifdef DEBUG
cout << (total_count+1) << "\t\t"
<< "Record Type = " << txtrec[0] << endl << "\t\t"
<< "Customer code = " << s1 << " - Invalid characters."
<< endl << "\t\t"
<< "Part Number = " << s2 << endl << "\t\t"
<< "Quantity = " << s3 << endl << endl;
#endif
prn_count++;
return validation_flag ;
}
else
sum = sum + (mych-48)*num_wt[i-1];
}
rem = sum%11;
if(rem == 0)
valid_char1 = 'X';
else if(rem == 1)
valid_char1 = '0';
else
valid_char1 = (char) (11-rem+48);

if(valid_char1 != txtrec[5])
{
validation_flag = false; // print with reason to printer
/* prn_file << (total_count+1) << "\t\t"
<< "Record Type = " << txtrec[0] << endl << "\t\t"
<< "Customer code = " << s1 << " - Invalid code."
<< endl << "\t\t"
<< "Part Number = " << s2 << endl << "\t\t"
<< "Quantity = " << s3 << endl << endl;*/
//
#ifdef DEBUG
cout << (total_count+1) << "\t\t"
<< "Record Type = " << txtrec[0] << endl << "\t\t"
<< "Customer code = " << s1 << " - Invalid code."
<< endl << "\t\t"
<< "Part Number = " << s2 << endl << "\t\t"
<< "Quantity = " << s3 << endl << endl;
#endif
//
prn_count++;
return validation_flag ;
}
else
{
sum = 0;
for(i=0; i<=4; i++)
{
mych = s2[i];
if(!isdigit(myc h))
{
validation_flag = false; // print with reason to printer
/* prn_file << (total_count+1) << "\t\t"
<< "Record Type = " << txtrec[0] << endl << "\t\t"
<< "Customer code = " << s1 << endl << "\t\t"
<< "Part Number = " << s2 << " - Invalid characters."
<< endl << "\t\t"
<< "Quantity = " << s3 << endl << endl;*/
#ifdef DEBUG
cout << (total_count+1) << "\t\t"
<< "Record Type = " << txtrec[0] << endl << "\t\t"
<< "Customer code = " << s1 << endl << "\t\t"
<< "Part Number = " << s2 << " - Invalid characters."
<< endl << "\t\t"
<< "Quantity = " << s3 << endl << endl;
#endif
prn_count++;
return validation_flag ;
}
else
sum = sum + (mych-48)*part_wt[i];
}
rem = sum%11;
if(rem == 0)
valid_char2 = 'X';
else if(rem == 1)
valid_char2 = '0';
else
valid_char2 = (char) (11-rem+48);
if(valid_char2 != txtrec[11])
{
validation_flag = false; // print with reason to printer
/* prn_file << (total_count+1) << "\t\t"
<< "Record Type = " << txtrec[0] << endl << "\t\t"
<< "Customer code = " << s1 << endl << "\t\t"
<< "Part Number = " << s2 << " - Invalid part number."
<< endl << "\t\t"
<< "Quantity = " << s3 << endl << endl;*/
//
#ifdef DEBUG
cout << (total_count+1) << "\t\t"
<< "Record Type = " << txtrec[0] << endl << "\t\t"
<< "Customer code = " << s1 << endl << "\t\t"
<< "Part Number = " << s2 << " - Invalid part number."
<< endl << "\t\t"
<< "Quantity = " << s3 << endl << endl;
#endif
//
prn_count++;
return validation_flag ;
}
else
{
for(i=0; i<=3; i++)
{
mych = s3[i];
if(!isdigit(myc h))
{
validation_flag = false; // print with reason to printer
/* prn_file << (total_count+1) << "\t\t"
<< "Record Type = " << txtrec[0] << endl << "\t\t"
<< "Customer code = " << s1 << endl << "\t\t"
<< "Part Number = " << s2 << endl << "\t\t"
<< "Quantity = " << s3 << " - Invalid characters."
<< endl << endl; */
#ifdef DEBUG
cout << (total_count+1) << "\t\t"
<< "Record Type = " << txtrec[0] << endl << "\t\t"
<< "Customer code = " << s1 << endl << "\t\t"
<< "Part Number = " << s2 << endl << "\t\t"
<< "Quantity = " << s3 << " - Invalid characters."
<< endl << endl;
#endif
prn_count++;
return validation_flag ;
}
}
irec.rec_type = txtrec[0];
strncpy(irec.cu st_code,s1,6);
strncpy(irec.pa rt_num,s2,7);
strncpy(irec.qu antity,s3,5);
valid_count++;
validation_flag = true;
nirec++;
#ifdef DEBUG
cout << "s1 = " << s1 << endl
<< "s2 = " << s2 << endl
<< "s3 = " << s3 << endl;
cout << "irec.cust_ code = " << irec.cust_code << endl;
cout << "irec.part_ num = " << irec.part_num << endl;
cout << "irec.quant ity = " << irec.quantity << endl;
#endif
//
IREC *irec_ptr;
irec_ptr = &irec;
valid_file.writ e((char *) irec_ptr, IREC_SIZE);
return validation_flag ;
}
}
}
//
bool validate_writeD (char* txtrec)
{
bool validation_flag = true;
int rem, sum = 0;
int num_wt[4] = {5, 4, 3, 2};
char mych, s1[6];
DREC drec;
//
for (int i=0; i<=4; i++)
{
mych = txtrec[i+1];
s1[i] = mych;
}
s1[5] = '\0';
for(i=0; i<4; i++)
{
mych = s1[i];
if(!isdigit(myc h))
{
validation_flag = false; // print with reason to printer
/* prn_file << (total_count+1) << "\t\t"
<< "Record Type = " << txtrec[0] << endl << "\t\t"
<< "Customer code = " << s1 << " - Invalid characters."
<< endl << endl;*/
#ifdef DEBUG
cout << (total_count+1) << "\t\t"
<< "Record Type = " << txtrec[0] << endl << "\t\t"
<< "Customer code = " << s1 << " - Invalid characters."
<< endl << endl;
#endif
prn_count++;
return validation_flag ;
}
else
sum = sum + (mych-48)*num_wt[i];
}
rem = sum%11;
if(rem == 0)
valid_char1 = 'X';
else if(rem == 1)
valid_char1 = '0';
else
valid_char1 = (char) (11-rem+48);
if(valid_char1 != txtrec[5])
{
validation_flag = false; // print with reason to printer
/* prn_file << (total_count+1) << "\t\t"
<< "Record Type = " << txtrec[0] << endl << "\t\t"
<< "Customer code = " << s1 << " - Invalid code."
<< endl << endl;*/
#ifdef DEBUG
cout << (total_count+1) << "\t\t"
<< "Record Type = " << txtrec[0] << endl << "\t\t"
<< "Customer code = " << s1 << " - Invalid code."
<< endl << endl;
#endif
//
prn_count++;
return validation_flag ;
}
else
{
drec.rec_type = txtrec[0];
strncpy(drec.cu st_code,s1,6);
valid_count++;
validation_flag = true;
#ifdef DEBUG
cout << "s1 = " << s1 << endl;
cout << "drec.cust_ code = " << drec.cust_code << endl;
#endif
ndrec++;

//
DREC *drec_ptr;
drec_ptr = &drec;
valid_file.writ e((char *) drec_ptr, DREC_SIZE);
return validation_flag ;
}
}
//
bool validate_writeC (char* txtrec)
{
char s5[8];
bool validation_flag = true;
int rem, sum = 0;
char s4[10];
int semicolon_cnt = 0;
char s1[6], s2[21];
int num_wt[4] = {5, 4, 3, 2};
char mych, mych_prev;
char s3[61];
CREC crec;
//
for(int i=1; i < 102; i++)
{
mych = txtrec[i];
if(i <= 5)
s1[i-1] = mych;
else if((i > 5) && (i <= 25))
s2[i-6] = mych;
else if((i > 25) && (i <= 85))
s3[i-26] = mych;
else if((i > 85) && (i <= 94))
s4[i-86] = mych;
else
s5[i-95] = mych;
}
s1[5] = '\0';
s2[20] = '\0';
s3[60] = '\0';
s4[10] = '\0';
s5[8] = '\0';
//
for(i=0; i<=3; i++)
{
mych = s1[i];
if(!isdigit(myc h))
{
validation_flag = false; // print with reason to printer
/* prn_file << (total_count+1) << "\t\t"
<< "Record Type = " << txtrec[0] << endl << "\t\t"
<< "Customer code = " << s1 << " - Invalid characters."
<< endl << "\t\t"
<< "Customer Name = " << s2 << endl << "\t\t"
<< "Address = " << s3 << endl << "\t\t"
<< "Customer Balance = " << s4 << endl << "\t\t"
<< "Credit Limit = " << s5 << endl << endl;*/
#ifdef DEBUG
cout << (total_count+1) << "\t\t"
<< "Record Type = " << txtrec[0] << endl << "\t\t"
<< "Customer code = " << s1 << " - Invalid characters."
<< endl << "\t\t"
<< "Customer Name = " << s2 << endl << "\t\t"
<< "Address = " << s3 << endl << "\t\t"
<< "Customer Balance = " << s4 << endl << "\t\t"
<< "Credit Limit = " << s5 << endl << endl;
#endif
prn_count++;
return validation_flag ;
}
else
sum = sum + (mych-48)*num_wt[i];
}
rem = sum%11;
if(rem == 0)
valid_char1 = 'X';
else if(rem == 1)
valid_char1 = '0';
else
valid_char1 = (char) (11-rem+48);
if(valid_char1 != txtrec[5])
{
validation_flag = false; // print with reason to printer
/* prn_file << (total_count+1) << "\t\t"
<< "Record Type = " << txtrec[0] << endl << "\t\t"
<< "Customer code = " << s1 << " - Invalid code."
<< endl << "\t\t"
<< "Customer Name = " << s2 << endl << "\t\t"
<< "Address = " << s3 << endl << "\t\t"
<< "Customer Balance = " << s4 << endl << "\t\t"
<< "Credit Limit = " << s5 << endl << endl;*/
#ifdef DEBUG
cout << (total_count+1) << "\t\t"
<< "Record Type = " << txtrec[0] << endl << "\t\t"
<< "Customer code = " << s1 << " - Invalid code."
<< endl << "\t\t"
<< "Customer Name = " << s2 << endl << "\t\t"
<< "Address = " << s3 << endl << "\t\t"
<< "Customer Balance = " << s4 << endl << "\t\t"
<< "Credit Limit = " << s5 << endl << endl;
#endif
prn_count++;
return validation_flag ;
}
else
{
for(i=6; i<=25; i++)
{
mych = txtrec[i];
if(!(isalpha(my ch)) && (mych != ' '))
{
validation_flag = false; // print with reason to printer
/* prn_file << (total_count+1) << "\t\t"
<< "Record Type = " << txtrec[0] << endl << "\t\t"
<< "Customer code = " << s1 << endl << "\t\t"
<< "Customer Name = " << s2 << " - Invalid characters."
<< endl << "\t\t"
<< "Address = " << s3 << endl << "\t\t"
<< "Customer Balance = " << s4 << endl << "\t\t"
<< "Credit Limit = " << s5 << endl << endl;*/
#ifdef DEBUG
cout << (total_count+1) << "\t\t"
<< "Record Type = " << txtrec[0] << endl << "\t\t"
<< "Customer code = " << s1 << endl << "\t\t"
<< "Customer Name = " << s2 << " - Invalid characters"
<< endl << "\t\t"
<< "Address = " << s3 << endl << "\t\t"
<< "Customer Balance = " << s4 << endl << "\t\t"
<< "Credit Limit = " << s5 << endl << endl;
#endif
//
prn_count++;
return validation_flag ;
}
}
for(i=26; i<=85; i++)
{
mych = txtrec[i];
if(mych != ';')
{
if((mych != '.') && (mych != ' ') &&
!(isalpha(mych) ))
{
if(!isdigit(myc h))
{
validation_flag = false; // Address field contains foul
characters
/* prn_file << (total_count+1) << "\t\t"
<< "Record Type = " << txtrec[0] << endl << "\t\t"
<< "Customer code = " << s1 << endl << "\t\t"
<< "Customer Name = " << s2 << endl << "\t\t"
<< "Address = " << s3 << endl << "\t\t"
<< "ERROR - WRONG CHARACTERS IN ADDRESS."
<< endl << "\t\t"
<< "Customer Balance = " << s4 << endl << "\t\t"
<< "Credit Limit = " << s5 << endl << endl;*/
#ifdef DEBUG
cout << (total_count+1) << "\t\t"
<< "Record Type = " << txtrec[0] << endl << "\t\t"
<< "Customer code = " << s1 << endl << "\t\t"
<< "Customer Name = " << s2 << endl << "\t\t"
<< "Address = " << s3 << endl << "\t\t"
<< "ERROR - WRONG CHARACTERS IN ADDRESS."
<< endl << "\t\t"
<< "Customer Balance = " << s4 << endl << "\t\t"
<< "Credit Limit = " << s5 << endl << endl;
#endif
prn_count++;
return validation_flag ;
}
else
{
if((i>26) && (semicolon_cnt == 0))
{
mych_prev = txtrec[i-1];
if(!isdigit(myc h))
{
validation_flag = false; // Address field contains foul
characters
/* prn_file << (total_count+1) << "\t\t"
<< "Record Type = " << txtrec[0] << endl << "\t\t"
<< "Customer code = " << s1 << endl << "\t\t"
<< "Customer Name = " << s2 << endl << "\t\t"
<< "Address = " << s3 << endl << "\t\t"
<< "ERROR - WRONG CHARACTERS IN ADDRESS."
<< endl << "\t\t"
<< "Customer Balance = " << s4 << endl << "\t\t"
<< "Credit Limit = " << s5 << endl << endl;*/
#ifdef DEBUG
cout << (total_count+1) << "\t\t"
<< "Record Type = " << txtrec[0] << endl << "\t\t"
<< "Customer code = " << s1 << endl << "\t\t"
<< "Customer Name = " << s2 << endl << "\t\t"
<< "Address = " << s3 << endl << "\t\t"
<< "ERROR - WRONG CHARACTERS IN ADDRESS."
<< endl << "\t\t"
<< "Customer Balance = " << s4 << endl << "\t\t"
<< "Credit Limit = " << s5 << endl << endl;
#endif
//
prn_count++;
return validation_flag ;
}
}
}
}
}
else
{
semicolon_cnt++ ;
if(semicolon_cn t > 4)
{
validation_flag = false; // too many semicolons in address field
/* prn_file << (total_count+1) << "\t\t"
<< "Record Type = " << txtrec[0] << endl << "\t\t"
<< "Customer code = " << s1 << endl << "\t\t"
<< "Customer Name = " << s2 << endl << "\t\t"
<< "Address = " << s3 << endl << "\t\t"
<< "ERROR - TOO MANY SEMI-COLONS IN ADDRESS."
<< endl << "\t\t"
<< "Customer Balance = " << s4 << endl << "\t\t"
<< "Credit Limit = " << s5 << endl << endl;*/
#ifdef DEBUG
cout << (total_count+1) << "\t\t"
<< "Record Type = " << txtrec[0] << endl << "\t\t"
<< "Customer code = " << s1 << endl << "\t\t"
<< "Customer Name = " << s2 << endl << "\t\t"
<< "Address = " << s3 << endl << "\t\t"
<< "ERROR - TOO MANY SEMI-COLONS IN ADDRESS."
<< endl << "\t\t"
<< "Customer Balance = " << s4 << endl << "\t\t"
<< "Credit Limit = " << s5 << endl << endl;
#endif
prn_count++;
return validation_flag ;
}
else
continue;
}
}
if(semicolon_cn t < 4)
{
validation_flag = false; // too few semicolons in address field
/* prn_file << (total_count+1) << "\t\t"
<< "Record Type = " << txtrec[0] << endl << "\t\t"
<< "Customer code = " << s1 << endl << "\t\t"
<< "Customer Name = " << s2 << endl << "\t\t"
<< "Address = " << s3 << endl << "\t\t"
<< "ERROR - TOO FEW SEMI-COLONS IN ADDRESS."
<< endl << "\t\t"
<< "Customer Balance = " << s4 << endl << "\t\t"
<< "Credit Limit = " << s5 << endl << endl;*/
#ifdef DEBUG
cout << (total_count+1) << "\t\t"
<< "Record Type = " << txtrec[0] << endl << "\t\t"
<< "Customer code = " << s1 << endl << "\t\t"
<< "Customer Name = " << s2 << endl << "\t\t"
<< "Address = " << s3 << endl << "\t\t"
<< "ERROR - TOO FEW SEMI-COLONS IN ADDRESS."
<< endl << "\t\t"
<< "Customer Balance = " << s4 << endl << "\t\t"
<< "Credit Limit = " << s5 << endl << endl;
#endif
//
prn_count++;
return validation_flag ;
}
// CUSTOMER BALANCE CHECK
for(i=86; i<=94; i++)
{
mych = txtrec[i];
if(!isdigit(myc h))
{
validation_flag = false;
/* prn_file << (total_count+1) << "\t\t"
<< "Record Type = " << txtrec[0] << endl << "\t\t"
<< "Customer code = " << s1 << endl << "\t\t"
<< "Customer Name = " << s2 << endl << "\t\t"
<< "Address = " << s3 << endl << "\t\t"
<< "Customer Balance = " << s4 << " - Non-numeric characters."
<< endl << "\t\t"
<< "Credit Limit = " << s5 << endl << endl;*/
#ifdef DEBUG
cout << (total_count+1) << "\t\t"
<< "Record Type = " << txtrec[0] << endl << "\t\t"
<< "Customer code = " << s1 << endl << "\t\t"
<< "Customer Name = " << s2 << endl << "\t\t"
<< "Address = " << s3 << endl << "\t\t"
<< "Customer Balance = " << s4 << " - Non-numeric characters."
<< endl << "\t\t"
<< "Credit Limit = " << s5 << endl << endl;
#endif
//
prn_count++;
return validation_flag ;
}
}
// CRIDIT LIMIT CHECK
for(i=95; i<=101; i++)
{
mych = txtrec[i];
if(!isdigit(myc h))
{
validation_flag = false;
/* prn_file << (total_count+1) << "\t\t"
<< "Record Type = " << txtrec[0] << endl << "\t\t"
<< "Customer code = " << s1 << endl << "\t\t"
<< "Customer Name = " << s2 << endl << "\t\t"
<< "Address = " << s3 << endl << "\t\t"
<< "Customer Balance = " << s4 << endl << "\t\t"
<< "Credit Limit = " << s5 << " - Non-numeric characters."
<< endl << endl;*/
cout << (total_count+1) << "\t\t"
<< "Record Type = " << txtrec[0] << endl << "\t\t"
<< "Customer code = " << s1 << endl << "\t\t"
<< "Customer Name = " << s2 << endl << "\t\t"
<< "Address = " << s3 << endl << "\t\t"
<< "Customer Balance = " << s4 << endl << "\t\t"
<< "Credit Limit = " << s5 << " - Non-numeric characters."
<< endl << endl;
prn_count++;
return validation_flag ;
}
}
#ifdef DEBUG
cout << "s1 = " << s1 << endl
<< "s2 = " << s2 << endl
<< "s3 = " << s3 << endl
<< "s4 = " << s4 << endl
<< "s5 = " << s5 << endl;
#endif
crec.rec_type = txtrec[0];
strncpy(crec.cu st_code, s1, 6);
strncpy(crec.cu st_name, s2, 21);
strncpy(crec.cu st_add, s3, 61);
strncpy(crec.cu st_balance, s4, 10);
strncpy(crec.cr edit_lim, s5, 8);
//
valid_count++;
validation_flag = true;
ncrec++;
//
CREC *crec_ptr;
crec_ptr = &crec;
valid_file.writ e((char *) crec_ptr, CREC_SIZE);
return validation_flag ;
}
}

//[END OF FILE: myheaderfileP1. h]

//[FILE: mymain.cpp]
#include "myheaderfileP1 .h"
//
char txtrec[MAXCHARS];
//
int main()
{
bool vflag;
char mych1;
//
trans_file.open ("mydata.DAT ", ios::in);
if(!trans_file. is_open())
{
cout << "Transactio n file is not opened" << endl;
exit(1);
}
//
/* prn_file.open(" lpt1", ios::out);
prn_file << "INVALID RECORDS FROM 534216TD.DAT" << endl
<< "---------------------------------" << endl << endl;
prn_file << "Record #\tReason for Invalidation" << endl
<< "--------\t-----------------------" << endl << endl;*/
//
valid_file.open ("mydataVF.DAT" , ios::out|ios::b inary);
if(!valid_file. is_open())
{
cout << "Validation file is not opened" << endl;
exit(1);
}
while(trans_fil e && !trans_file.eof ())
{
trans_file.getl ine(txtrec, 103, '\n');
mych1 = toupper(txtrec[0]);
switch(mych1)
{
case 'I':
case 'R':
{
vflag = validate_writeI (txtrec);
total_count++;
break;
}
case 'C':
{
vflag = validate_writeC (txtrec);
total_count++;
break;
}
case 'D':
{
vflag = validate_writeD (txtrec);
total_count++;
break;
}
default:
break;
}
if((mych1 != 'I') && (mych1 != 'R') &&
(mych1 != 'C') && (mych1 != 'D'))
{
if(isalpha(mych 1))
{
/* prn_file << (total_count+1) << "\t\t"
<< "Invalid record type."
<< endl;*/
cout << (total_count+1) << "\t\t"
<< "Invalid record type."
<< endl;
prn_count++;
total_count++;
}
}
}
/* prn_file << endl << endl << "Invalid records:\t"
<< setiosflags(ios ::right) << setw(3)
<< prn_count << endl;
prn_file << "Valid records:\t\t"
<< setiosflags(ios ::right) << setw(3)
<< valid_count << endl;
prn_file << "Total records checked:\t"
<< setiosflags(ios ::right) << setw(3)
<< total_count << endl << endl;
prn_file << "End of file reached. Exitting normally." << endl;*/
//
cout << endl << endl << "Invalid records:\t"
<< prn_count << endl;
cout << "Valid records:\t\t"
<< valid_count << endl;
cout << "Total records checked:\t"
<< total_count << endl << endl;
cout << "End of file reached. Exitting normally." << endl;
//
return 0;
}
// [END OF FILE: mymain.cpp]

// [FILE mydata.dat]
I24686245682005 6
R24680245686408 9
R35785456900203 7
D25402
D45900
D4590X
C45675Mahmood Ahmad 16 Greywethers Avenue;Old Town;Swindon
Wiltshire SN3 1QF; 604509.50100000 0
C45675Mahmood Ahmad Greywethers 16 Avenue;Old Town;Swindon
Wiltshire SN3 QFF; 604509.50100000 0
C45675Mahmood A9mad 16 Greywethers Avenue;Old Town;Swindon
Wiltshire SN3 1QF; 604509.50100000 0
C90875Mrs Gwen Metcalfe 10 Bydemill Gardens;Highwor th
Swindon;Wiltshi re;SN6 7BT 455609.75250000 0
C90875Mrs Gwen Metcalfe 10 Bydemill Gardens;Highwor th
Swindon;Wiltshi re;SN6 7BT 455609.752500M0 0
C90875Mrs Gwen Metcalfe 10 Bydemill
Gardens;Highwor th;Swindon;Wilt shire;SN6 7BT 455609.75250000 0
D29904
C99996Mr D Gupta Ridgeway Hospital;Moreme ad Road;Wroughton
Swindon;SN4 4DD 009000.00040000 0
R00121450500987
M34002
D34002
[END OF FILE]
Jul 22 '05 #1
3 2977
Mahmood Ahmad wrote:
Hello,

I have written a program that reads three types of records, validates
them acording to certain requirements and writes the valid records
into a binary file. The invalid records are supposed to be reported on
the printer but I have commented those pieces of code and have got
those records printed on the screen. I am using Microsoft Visual C++
6.0 on Microsoft XP (Home) platform.

I am facing some problems in getting desire results:

1. My program runs with some abnormal termination at the very end
(which is the return 0; line at the end of mymain.cpp).

2.The output saved in the validated file mydataVF.dat is also consists
of characters beyond my expectation.

3. In the function validate_writeC (...), you will find the strings as
local variables spread among various lines in function header. I have
done so, because my program overwrites or "loses" certain strings in
this function if I define all those strings in one line like:

char s1[6], s2[21], s3[61], s4[10], s5[8];

Does this happen because the memory locations for these strings are
contiguous and my program tends to overwrite some of the important
data? Does this have something to do with the size of local variables
for a function? How can I remedy these problems?

Grateful for help,


[rather excessive code snipped]

An error like this *very* much suggests that your're overwriting an
automatic (i.e.local) array (perhaps by failing to allow sufficient
space for a trailing nul in a C-style string).

There's no way I'm going to look at hundreds of lines of code with a
fine-toothed comb; indeed, it is quite inappropriate to post so much code.

In the future, please include, as part of the message, the smallest,
compilable/runnable snippet of code that exhibits the problem. This has
two great advantages: 1) Those who *can* help are much more likely to
read your code carefully, and 2) You are likely to find your problem
(i.e. the bug) in the process.

HTH,
--ag

--
Artie Gold -- Austin, Texas

"Yeah. It's an urban legend. But it's a *great* urban legend!"
Jul 22 '05 #2
On 18 Feb 2004 16:43:01 -0800 in comp.lang.c++,
ma************* @yahoo.com (Mahmood Ahmad) was alleged to have written:
Does this happen because the memory locations for these strings are
contiguous and my program tends to overwrite some of the important
data? Does this have something to do with the size of local variables
for a function? How can I remedy these problems?
It happens because some of your array indexes exceeds the array
boundary, and so the char you store there clobbers some other memory.

For example:
typedef struct {
char rec_type;
char cust_code[6];
char part_num[7];
char quantity[5];
} IREC;
Here IREC is a minimum of 19 bytes.
char s1[6], s2[7], s3[5];
//
for(int i=1; i<sizeof(IREC) ; i++)
{
mych = txtrec[i];
if(i <= 5)
s1[i-1] = mych;
else if((i > 5) && (i <= 11))
s2[i-6] = mych;
else
s3[i-12] = mych;


When i is 17, (i-12) is 5 and s3[5] writes past the end of s3.
And you still have i=18 to go.

You have dozens of little bitty magic numbers like 17, 12, 5, etc.
scattered all over your code. Every one of them is a potential
disaster. Nobody can write code like that for long and remain sane.
Fix things so you don't have to count chars more than once each.
At least, declare consts for the number of chars in each field, and
define everything else in terms of them.

Jul 22 '05 #3
Hello again,

Here is a simplified version of the code which I have tried to modify
too, in the light of your responses. After changing plenty of numbers
to appropriately defined constants, and reviewing the logic of my
program, my program has a normal termination now. However, it still
saves strange characters in the valid_file, strange becuse the
characters are unexpected.

This program reads a line from a text file. Each line read contains
record of one of three types IREC, CREC and DREC. All this program
does is read the line, separate the fields into strings, copy those
strings into fields of appropriate record type and write the record
into a binary file.

I have checked and debugged to see if all the strings get the expected
characters (in number and in content). Everything seems to work fine.
However, in the process of closing the file, some thing has gone wrong
which I do not know.

I hope the present code is of appropriate size. I would appreciate for
your help.

Thanks,

Mahmood.

Here is the code and the example data:

#include <iostream>

using std::cout;
using std::endl;
using std::ios;

#include <string>

using std::string;

#include <fstream>

using std::ifstream;
using std::ofstream;

#include <iomanip>

using std::setprecisi on;
using std::setiosflag s;
using std::resetiosfl ags;
using std::setw;
//
#include <cstdlib>
#include <ctype.h>
//
#define FOUR 4
#define CUSTCODE 6
#define PARTNUMB 7
#define QUANTITI 5
#define CREDITLIM 8
#define CUSTNAME 21
#define CUSTADDR 61
#define BALANCE 10
//
#define MAXCHARS 103
//
typedef struct {
char rec_type;
char cust_code[CUSTCODE];
char part_num[PARTNUMB];
char quantity[QUANTITI];
} IREC;
//
typedef struct {
char rec_type;
char cust_code[CUSTCODE];
} DREC;
//
typedef struct {
char rec_type;
char cust_code[CUSTCODE];
char cust_name[CUSTNAME];
char cust_add[CUSTADDR];
char cust_balance[BALANCE];
char credit_lim[CREDITLIM];
} CREC;
//
#define IREC_SIZE sizeof(IREC)
#define CREC_SIZE sizeof(CREC)
#define DREC_SIZE sizeof(DREC)
//
ifstream trans_file;
ofstream valid_file;
//
int total_count = 0;
int prn_count = 0;
char valid_char1, valid_char2;
char txtrec[MAXCHARS];
//
bool validate_writeI (char* txtrec);
bool validate_writeC (char* txtrec);
bool validate_writeD (char* txtrec);
//
int main()
{
bool vflag;
char mych1;
//
trans_file.open ("mydata.DAT ", ios::in);
if(!trans_file. is_open())
{
cout << "Transactio n file is not opened" << endl;
exit(1);
}
valid_file.open ("mydataVF.DAT" , ios::out|ios::b inary);
if(!valid_file. is_open())
{
cout << "Validation file is not opened" << endl;
exit(1);
}
while(trans_fil e && !trans_file.eof ())
{
trans_file.getl ine(txtrec, MAXCHARS, '\n');
mych1 = toupper(txtrec[0]);
switch(mych1)
{
case 'I':
case 'R':
{
vflag = validate_writeI (txtrec);
total_count++;
break;
}
case 'C':
{
vflag = validate_writeC (txtrec);
total_count++;
break;
}
case 'D':
{
vflag = validate_writeD (txtrec);
total_count++;
break;
}
default:
break;
}
if((mych1 != 'I') && (mych1 != 'R') &&
(mych1 != 'C') && (mych1 != 'D'))
{
if(isalpha(mych 1))
{
cout << (total_count+1) << "\t"
<< "Invalid record type."
<< endl;
prn_count++;
total_count++;
}
}
}
cout << "Total records checked:\t"
<< total_count << endl << endl;
cout << "End of file reached. Exitting normally." << endl;
//
return 0;
}
//
bool validate_writeI (char* txtrec)
{
bool validation_flag = true;
IREC irec;
char mych;
char s1[CUSTCODE], s2[PARTNUMB], s3[QUANTITI];
//
// First, separating each field into strings
for(int i=1; i<(IREC_SIZE-3); i++)
{
mych = txtrec[i];
if(i <= (CUSTCODE-1))
s1[i-1] = mych;
else if((i > (CUSTCODE-1)) && (i <= (CUSTCODE+PARTN UMB-2)))
s2[i-CUSTCODE] = mych;
else
s3[i-(CUSTCODE+PARTN UMB-1)] = mych;
}
// Appending null character to the end of each string.
s1[CUSTCODE-1] = '\0';
s2[PARTNUMB-1] = '\0';
s3[QUANTITI-1] = '\0';
// Saving strings into record fields
irec.rec_type = txtrec[0];
strncpy(irec.cu st_code,s1,CUST CODE);
strncpy(irec.pa rt_num,s2,PARTN UMB);
strncpy(irec.qu antity,s3,QUANT ITI);
validation_flag = true;
//
// Saving the record into te binary file.
IREC *irec_ptr;
irec_ptr = &irec;
valid_file.writ e((char *) irec_ptr, IREC_SIZE);
return validation_flag ;
}
//
bool validate_writeD (char* txtrec)
{
bool validation_flag = true;
char mych, s1[CUSTCODE];
DREC drec;
//
// saving in string
for (int i=1; i<DREC_SIZE; i++)
{
mych = txtrec[i];
s1[i-1] = mych;
}
s1[CUSTCODE-1] = '\0'; // Append null character at the end.
// Save the string in the record
drec.rec_type = txtrec[0];
strncpy(drec.cu st_code,s1,CUST CODE);
cout << "cust_code = " << s1 << endl;
valid_count++;
validation_flag = true;
//
// Write record in the file
DREC *drec_ptr;
drec_ptr = &drec;
valid_file.writ e((char *) drec_ptr, DREC_SIZE);
return validation_flag ;
}
//
bool validate_writeC (char* txtrec)
{
char s1[CUSTCODE], s2[CUSTNAME], s3[CUSTADDR];
char s4[BALANCE], s5[CREDITLIM];
bool validation_flag = true;
char mych;
//
// separate record fields into strings
for(int i=1; i < 102; i++)
{
mych = txtrec[i];
if(i <= (CUSTCODE-1))
s1[i-1] = mych;
else if((i > (CUSTCODE-1)) && (i <= (CUSTCODE+CUSTN AME-2)))
s2[i-CUSTCODE] = mych;
else if((i > (CUSTCODE+CUSTN AME-2)) &&
(i <= (CUSTCODE+CUSTN AME+CUSTADDR-3)))
s3[i-(CUSTCODE+CUSTN AME-1)] = mych;
else if((i > (CUSTCODE+CUSTN AME+CUSTADDR-3))
&& (i <= (CUSTCODE+CUSTN AME+CUSTADDR+BA LANCE-4)))
s4[i-(CUSTCODE+CUSTN AME+CUSTADDR-2)] = mych;
else
s5[i-(CUSTCODE+CUSTN AME+CUSTADDR+BA LANCE-3)] = mych;
}
// Append null character at the end
s1[CUSTCODE-1] = '\0';
s2[CUSTNAME-1] = '\0';
s3[CUSTADDR-1] = '\0';
s4[BALANCE-1] = '\0';
s5[CREDITLIM-1] = '\0';
// save these strings into the record field
CREC crec;
crec.rec_type = txtrec[0];
strcpy(crec.cus t_code, s1);
strcpy(crec.cus t_name, s2);
strcpy(crec.cus t_add, s3);
strcpy(crec.cus t_balance, s4);
strcpy(crec.cre dit_lim, s5);
//
validation_flag = true;
//
// writing record into the file.
CREC *crec_ptr;
crec_ptr = &crec;
valid_file.writ e((char *)crec_ptr, CREC_SIZE);
return validation_flag ;
}
END OF PROGRAM
File: mydata.dat
I24686245682005 6
R24680245686408 9
R35785456900203 7
D25402
D45900
D4590X
C45675Mahmood Ahmad 16 Greywethers Avenue;Old Town;Swindon
Wiltshire SN3 1QF; 604509.50100000 0
C45675Mahmood Ahmad Greywethers 16 Avenue;Old Town;Swindon
Wiltshire SN3 QFF; 604509.50100000 0
C45675Mahmood A9mad 16 Greywethers Avenue;Old Town;Swindon
Wiltshire SN3 1QF; 604509.50100000 0
C90875Mrs Gwen Metcalfe 10 Bydemill Gardens;Highwor th
Swindon;Wiltshi re;SN6 7BT 455609.75250000 0
C90875Mrs Gwen Metcalfe 10 Bydemill Gardens;Highwor th
Swindon;Wiltshi re;SN6 7BT 455609.752500M0 0
C90875Mrs Gwen Metcalfe 10 Bydemill
Gardens;Highwor th;Swindon;Wilt shire;SN6 7BT 455609.75250000 0
D29904
C99996Mr D Gupta Ridgeway Hospital;Moreme ad Road;Wroughton
Swindon;SN4 4DD 009000.00040000 0
R00121450500987
M34002
D34002
David Harmon <so****@netcom. com> wrote in message news:<40******* *********@news. west.earthlink. net>...
On 18 Feb 2004 16:43:01 -0800 in comp.lang.c++,
ma************* @yahoo.com (Mahmood Ahmad) was alleged to have written:
Does this happen because the memory locations for these strings are
contiguous and my program tends to overwrite some of the important
data? Does this have something to do with the size of local variables
for a function? How can I remedy these problems?


It happens because some of your array indexes exceeds the array
boundary, and so the char you store there clobbers some other memory.

For example:
typedef struct {
char rec_type;
char cust_code[6];
char part_num[7];
char quantity[5];
} IREC;


Here IREC is a minimum of 19 bytes.
char s1[6], s2[7], s3[5];
//
for(int i=1; i<sizeof(IREC) ; i++)
{
mych = txtrec[i];
if(i <= 5)
s1[i-1] = mych;
else if((i > 5) && (i <= 11))
s2[i-6] = mych;
else
s3[i-12] = mych;


When i is 17, (i-12) is 5 and s3[5] writes past the end of s3.
And you still have i=18 to go.

You have dozens of little bitty magic numbers like 17, 12, 5, etc.
scattered all over your code. Every one of them is a potential
disaster. Nobody can write code like that for long and remain sane.
Fix things so you don't have to count chars more than once each.
At least, declare consts for the number of chars in each field, and
define everything else in terms of them.

Jul 22 '05 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
3427
by: John Pote | last post by:
Running my programme in Python 2.3.4 I received the following msg in the consol :- (Pent III running W2K prof) """ Exception in Tkinter callback Traceback (most recent call last): File "c:\apps\python\234\lib\lib-tk\Tkinter.py", line 1345, in __call__ return self.func(*args) File "c:\apps\python\234\lib\lib-tk\Tkinter.py", line 459, in callit
1
4500
by: R6_2003 | last post by:
Hello all, i dunno if that's the right newsgroup to ask, but i'll try, please ignore me if u feel its not 0:) i've been messing with a control panel app for so long.. previously i was using Microsoft Visual C++ 6 and had ZERO problems, but now at work we switched to Borland C++ 6.0. The control panel applet i did contains a simple form with a
2
2142
by: Hugh | last post by:
Hello, Apologies if this has already been answered in here and I can't find it, but can anyone help with this problem? I hope the example code and comments state clearly enough what is happening, but if not, please ask me for further information. Thank in advance for any help. :-) Hugh
0
1867
by: Alexander F?hrmann | last post by:
Grüß euch! Wir haben hier in der Firma ein Problem mit Access! Sobald man im Access den VBA-Editor aufrufen will, kommt folgender fehler! -------------------- Runtime Error!
16
5211
by: PyDenis | last post by:
Today, I found strange error while using py2exe: 1. I wrote simple program and save as 1.py: import win32ui import win32con win32ui.MessageBox('Test messageBox.' , 'Test', win32con.MB_OK | win32con.MB_TOPMOST ) 2. I create 1_setup.py file for py2exe:
9
6898
by: ehabaziz2001 | last post by:
I am facing that error message with no idea WHY the reason ? "Abnormal program termination" E:\programs\c_lang\iti01\tc201\ch06\ownarr01o01 Enter a number : 25 More numbers (y/n)? y Enter a number : 30 More numbers (y/n)? n
6
45248
by: helpswat4 | last post by:
I was wondering if someone could help me with this problem...i get a runtime error everytime i try to play Swat 4 on my PC.It says abnormal program termination and i have no idea why....could someone please respond and let me know how to fix this...or if it can even be fixed??
6
1753
by: k3xji | last post by:
Hi all, Is there anyway to detect abnormal interpreter shutdown like (closing from task manager, power shutdown of the PC..etc)? Regards,
1
5089
by: qzhang | last post by:
I get that error message everytime i try to play freedom force vs 3rd reich game its not that much of an older game and i'm trying to play it on my vista laptop please help
0
8725
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
9360
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
7993
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6658
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5971
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4481
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4744
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3185
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
2124
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.