473,387 Members | 3,821 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

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::setprecision;
using std::setiosflags;
using std::resetiosflags;
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(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 << " - 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(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"
<< "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(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"
<< "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.cust_code,s1,6);
strncpy(irec.part_num,s2,7);
strncpy(irec.quantity,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.quantity = " << irec.quantity << endl;
#endif
//
IREC *irec_ptr;
irec_ptr = &irec;
valid_file.write((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(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 << " - 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.cust_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.write((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(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 << " - 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(mych)) && (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(mych))
{
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(mych))
{
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_cnt > 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_cnt < 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(mych))
{
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(mych))
{
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.cust_code, s1, 6);
strncpy(crec.cust_name, s2, 21);
strncpy(crec.cust_add, s3, 61);
strncpy(crec.cust_balance, s4, 10);
strncpy(crec.credit_lim, s5, 8);
//
valid_count++;
validation_flag = true;
ncrec++;
//
CREC *crec_ptr;
crec_ptr = &crec;
valid_file.write((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 << "Transaction 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::binary);
if(!valid_file.is_open())
{
cout << "Validation file is not opened" << endl;
exit(1);
}
while(trans_file && !trans_file.eof())
{
trans_file.getline(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(mych1))
{
/* 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]
I246862456820056
R246802456864089
R357854569002037
D25402
D45900
D4590X
C45675Mahmood Ahmad 16 Greywethers Avenue;Old Town;Swindon
Wiltshire SN3 1QF; 604509.501000000
C45675Mahmood Ahmad Greywethers 16 Avenue;Old Town;Swindon
Wiltshire SN3 QFF; 604509.501000000
C45675Mahmood A9mad 16 Greywethers Avenue;Old Town;Swindon
Wiltshire SN3 1QF; 604509.501000000
C90875Mrs Gwen Metcalfe 10 Bydemill Gardens;Highworth
Swindon;Wiltshire;SN6 7BT 455609.752500000
C90875Mrs Gwen Metcalfe 10 Bydemill Gardens;Highworth
Swindon;Wiltshire;SN6 7BT 455609.752500M00
C90875Mrs Gwen Metcalfe 10 Bydemill
Gardens;Highworth;Swindon;Wiltshire;SN6 7BT 455609.752500000
D29904
C99996Mr D Gupta Ridgeway Hospital;Moremead Road;Wroughton
Swindon;SN4 4DD 009000.000400000
R00121450500987
M34002
D34002
[END OF FILE]
Jul 22 '05 #1
3 2947
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::setprecision;
using std::setiosflags;
using std::resetiosflags;
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 << "Transaction file is not opened" << endl;
exit(1);
}
valid_file.open("mydataVF.DAT", ios::out|ios::binary);
if(!valid_file.is_open())
{
cout << "Validation file is not opened" << endl;
exit(1);
}
while(trans_file && !trans_file.eof())
{
trans_file.getline(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(mych1))
{
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+PARTNUMB-2)))
s2[i-CUSTCODE] = mych;
else
s3[i-(CUSTCODE+PARTNUMB-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.cust_code,s1,CUSTCODE);
strncpy(irec.part_num,s2,PARTNUMB);
strncpy(irec.quantity,s3,QUANTITI);
validation_flag = true;
//
// Saving the record into te binary file.
IREC *irec_ptr;
irec_ptr = &irec;
valid_file.write((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.cust_code,s1,CUSTCODE);
cout << "cust_code = " << s1 << endl;
valid_count++;
validation_flag = true;
//
// Write record in the file
DREC *drec_ptr;
drec_ptr = &drec;
valid_file.write((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+CUSTNAME-2)))
s2[i-CUSTCODE] = mych;
else if((i > (CUSTCODE+CUSTNAME-2)) &&
(i <= (CUSTCODE+CUSTNAME+CUSTADDR-3)))
s3[i-(CUSTCODE+CUSTNAME-1)] = mych;
else if((i > (CUSTCODE+CUSTNAME+CUSTADDR-3))
&& (i <= (CUSTCODE+CUSTNAME+CUSTADDR+BALANCE-4)))
s4[i-(CUSTCODE+CUSTNAME+CUSTADDR-2)] = mych;
else
s5[i-(CUSTCODE+CUSTNAME+CUSTADDR+BALANCE-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.cust_code, s1);
strcpy(crec.cust_name, s2);
strcpy(crec.cust_add, s3);
strcpy(crec.cust_balance, s4);
strcpy(crec.credit_lim, s5);
//
validation_flag = true;
//
// writing record into the file.
CREC *crec_ptr;
crec_ptr = &crec;
valid_file.write((char *)crec_ptr, CREC_SIZE);
return validation_flag;
}
END OF PROGRAM
File: mydata.dat
I246862456820056
R246802456864089
R357854569002037
D25402
D45900
D4590X
C45675Mahmood Ahmad 16 Greywethers Avenue;Old Town;Swindon
Wiltshire SN3 1QF; 604509.501000000
C45675Mahmood Ahmad Greywethers 16 Avenue;Old Town;Swindon
Wiltshire SN3 QFF; 604509.501000000
C45675Mahmood A9mad 16 Greywethers Avenue;Old Town;Swindon
Wiltshire SN3 1QF; 604509.501000000
C90875Mrs Gwen Metcalfe 10 Bydemill Gardens;Highworth
Swindon;Wiltshire;SN6 7BT 455609.752500000
C90875Mrs Gwen Metcalfe 10 Bydemill Gardens;Highworth
Swindon;Wiltshire;SN6 7BT 455609.752500M00
C90875Mrs Gwen Metcalfe 10 Bydemill
Gardens;Highworth;Swindon;Wiltshire;SN6 7BT 455609.752500000
D29904
C99996Mr D Gupta Ridgeway Hospital;Moremead Road;Wroughton
Swindon;SN4 4DD 009000.000400000
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
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...
1
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...
2
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...
0
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
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 |...
9
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...
6
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...
6
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
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
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
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...
0
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,...

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.