std::sort whole program

J

JasBascom

I thought it was too much to put this program in with my last message. The
program compiles ok, but when I execute, I get access errors.
can someone put it through their compiler please. I think the problem lies
when i declare union Allrecords h1,h2,h3.
and then use them to toupper record_type. the debug when i use it can not go
past the switch statement.
thank you for you help




#include <iostream>
#include <iomanip>
#include <fstream>
#include <cstring>
#include <cstdlib>


using namespace std;

struct crecord {
char record_type;
char customercode[6];
char customername[21];
char customeraddress[61];
char customerbalance;
char creditlimit;
};
crecord Newcrecord;

struct irrecord {
char record_type;
char customercode[6];
char partnum[7];
char issue_rec;

};
irrecord Newirrecord;

struct drecord {
char record_type;
char customercode[6];
};
drecord Newdrecord;

union Allrecords {
struct crecord Newcrecord;
struct irrecord Newirrecord;
struct drecord Newdrecord;
};

const int list = 200;
int loop = 200;

union Allrecords records
  • ;
    union Allrecords *rec = records;

    void sort_function( union Allrecords *rec, ifstream& validdata )
    {

    union Allrecords *str_ptr1 = rec;
    union Allrecords *str_ptr2, tempstr;


    for(int i =0; i< loop; i++)
    while( strcmp(str_ptr1.Newcrecord.customercode, '\0') ||
    strcmp(str_ptr1.Newdrecord.customercode, '\0') ||
    strcmp(str_ptr1.Newirrecord.customercode, '\0'))
    {
    str_ptr2 = str_ptr1 + 1;//set to next element.

    for( i=0; i<loop; i++)
    while( strcmp(str_ptr2.Newcrecord.customercode, '\0') ||
    strcmp(str_ptr2.Newdrecord.customercode, '\0'))
    {
    for(int i=0; i<loop; i++)
    if( strcmp( str_ptr1.Newirrecord.customercode,
    str_ptr2.Newirrecord.customercode + 1))
    {
    tempstr = *str_ptr1;
    *str_ptr1 = *str_ptr2;
    *str_ptr2 = tempstr;

    }
    *str_ptr1++;//incremented, so that the same code isn't sorted again
    }
    str_ptr2++;
    }

    }


    int main()
    {

    union Allrecords h1, h2, h3;

    h1.Newcrecord.record_type = 'c';
    h1.Newcrecord.record_type = toupper(Newcrecord.record_type);




    h2.Newirrecord.record_type = 'i' | 'r';
    h2.Newirrecord.record_type = toupper(Newirrecord.record_type);


    h3.Newdrecord.record_type = 'd';
    h3.Newdrecord.record_type = toupper(Newdrecord.record_type);


    const char outfile[] = "A:\\514650VDP1.bin";
    const char infile[] = "A:\\514650SD.txt";

    long offset = 0;
    int filesize;
    int reccount;



    ifstream validdata;
    fstream sortfile;

    validdata.open("A:\\514650VDP1.bin", ios::in | ios::binary);
    if(!validdata)
    {
    cout<< " Unable to open file" <<endl;
    exit(1);
    };

    sortfile.open("A:\\514650SD.txt", ios::eek:ut);
    if(!sortfile)
    {
    cout<< "Cannot create file" << endl;
    exit(1);
    };

    validdata.seekg(0, ios::end);
    filesize = validdata.tellg();
    validdata.seekg(offset, ios::beg);

    reccount = filesize/sizeof(Allrecords);
    rec = new(Allrecords[reccount]);

    validdata.read((char*) &rec, filesize);

    for(int i = 0; i <reccount; i++)
    {
    switch(rec.Newdrecord.record_type)
    {
    case 'c':
    case 'C':
    case 'd':
    case 'D':
    case 'i':
    case 'I':
    case 'r':
    case 'R':
    sort_function1();
    default:;
    };

    };
    validdata.close();
    sortfile.close();

    return 0;


    };
 
J

John Harrison

JasBascom said:
I thought it was too much to put this program in with my last message. The
program compiles ok, but when I execute, I get access errors.
can someone put it through their compiler please. I think the problem lies
when i declare union Allrecords h1,h2,h3.
and then use them to toupper record_type. the debug when i use it can not go
past the switch statement.
thank you for you help

If this is the exact code then there are definitely a few things wrong,
frankly its not worth running until those are fixed. In fact if this is the
exact code, then it won't compile because you are trying to call a function
called sort_function1 when there is no such function in your code (there's
sort_function but not a sort_function1).
validdata.read((char*) &rec, filesize);

This is wrong, I know this has been discussed before but trust me

validdata.read((char*)rec, filesize);

After all you say you can't get past the switch statement, which suggests to
me that what is immediately before the switch statement is wrong, no?
for(int i = 0; i <reccount; i++)
{
switch(rec.Newdrecord.record_type)
{
case 'c':
case 'C':
case 'd':
case 'D':
case 'i':
case 'I':
case 'r':
case 'R':
sort_function1();
default:;
};


The whole loop is misconcieved. The sort function is meant to sort the
entire array, so it needs to be called once for the whole array, not once
for each record which is what you are doing.

I would suggest you forget about the sort for now. If you can just get the
read to work it would be progress, then if you can just get the write to a
text file to work (obviously that means writing out unsorted data) then that
will be great progress. Leave the sort to last, its the hardest part.

Do you know what is in the binary file you are reading? I would suggest you
write some code like this

validdata.read((char*)rec, filesize);
for(int i = 0; i <reccount; i++)
{
cout << rec.Newcrecord.record_type << ' '
rec.Newcrecord.customercode << '\n';
}

Just to see if the read has worked.

john
 
T

Thomas Matthews

JasBascom said:
I thought it was too much to put this program in with my last message. The
program compiles ok, but when I execute, I get access errors.
can someone put it through their compiler please. I think the problem lies
when i declare union Allrecords h1,h2,h3.
and then use them to toupper record_type. the debug when i use it can not go
past the switch statement.
thank you for you help
Don't Top-post. Replies go at the bottom or
interspersed (like this one). Fix your newsreader.

A good idea is to refresh your knowledge on netiquette:
http://www.parashift.com/c++-faq-lite/how-to-post.html

#include <iostream>
#include <iomanip>
#include <fstream>
#include <cstring>
#include <cstdlib>


using namespace std;

struct crecord {
char record_type;
char customercode[6];
char customername[21];
char customeraddress[61];
char customerbalance;
char creditlimit;
};
crecord Newcrecord;

struct irrecord {
char record_type;
char customercode[6];
char partnum[7];
char issue_rec;

};
irrecord Newirrecord;

struct drecord {
char record_type;
char customercode[6];
};
drecord Newdrecord;
1. Use named constants:
const unsigned int MAX_CUST_CODE_LENGTH = 6;
//...
char customercode[MAX_CUST_CODE_LENGTH];

You may want to invest in inheritance:
struct record_common
{
char record_type; // this may want to be an int.
char customercode[MAX_CUST_CODE_LENGTH];
};

struct crecord
: public record_common
{
char customername[21];
char customeraddress[61];
char customerbalance;
char creditlimit;
};

struct irrecord
: public record_common
{
char partnum[7];
char issue_rec;
};

typedef record_common drecord; // a drecord is a record_common.
union Allrecords {
struct crecord Newcrecord;
struct irrecord Newirrecord;
struct drecord Newdrecord;
};

const int list = 200;
int loop = 200;

union Allrecords records
  • ;
    union Allrecords *rec = records;


  • With using inheritance, you could use a std::vector of
    pointers to the base class:
    std::vector<record_common> record_ptrs[MAX_RECORDS];

    Every record is guaranteed to have at least the record_type
    and customercode fields.

    [sort function snipped]
    I highly suggest you reorganize your data before you think
    of sorting it. For example, you could convert the data
    into Normal Forms (database theory).

    Sorting different types of records doesn't really make
    sense.


    int main()
    {

    union Allrecords h1, h2, h3;

    h1.Newcrecord.record_type = 'c';
    h1.Newcrecord.record_type = toupper(Newcrecord.record_type);
    Simplified [1]:
    h1.Newcrecord.record_type = toupper('c');
    or:
    h1.Newcrecord.record_type = 'C';

    Simplified [2]:
    record_common * h1;
    record_common * h2;
    record_common * h3;

    h1 = new crecord;
    h2 = new irecord;
    h3 = new drecord;
    record_ptrs[0] = h1;
    record_ptrs[1] = h2;
    record_ptrs[2] = h3;

    h2.Newirrecord.record_type = 'i' | 'r';
    The '|' character is a bitwise (arithmetic) "OR" not a logical one.
    So if 'i' is 0x69 and 'r' is 0x72, then:
    'i' | 'r' == 0x69 | 0x72
    ==
    0110 1001
    0111 0010
    ---------
    0111 1011 == 0x7B
    I don't think this is what you want.
    I believe you want to have a constructor function in the structures
    that sets the record type automatically:
    struct record_common
    {
    // same members
    record_common(char new_record_type)
    : record_type(new_record_type)
    { ; }
    };

    struct irrecord
    : public record_common
    {
    // same members as above
    irrecord()
    : record_common('i') // sets record type to 'i'
    { ; }
    };

    struct crecord
    : public record_common
    {
    // same members as above
    crecord()
    : record_common('c')
    { ; }
    };

    h2.Newirrecord.record_type = toupper(Newirrecord.record_type);


    h3.Newdrecord.record_type = 'd';
    h3.Newdrecord.record_type = toupper(Newdrecord.record_type);


    const char outfile[] = "A:\\514650VDP1.bin";
    const char infile[] = "A:\\514650SD.txt";

    long offset = 0;
    int filesize;
    int reccount;



    ifstream validdata;
    fstream sortfile;

    validdata.open("A:\\514650VDP1.bin", ios::in | ios::binary);
    Should be:
    validdata.open(outfile, ios::in | ios::binary);

    if(!validdata)
    {
    cout<< " Unable to open file" <<endl;
    /******/ cout << "Unable to open file: " << outfile << endl;

    /******/ return EXIT_FAILURE;

    };

    sortfile.open("A:\\514650SD.txt", ios::eek:ut);
    /******/sortfile.open(infile, ios::eek:ut);

    if(!sortfile)
    {
    cout<< "Cannot create file" << endl;
    /******/ cout << "Cannot create file:" << infile << endl;

    /******/ return EXIT_FAILURE;

    };

    validdata.seekg(0, ios::end);
    filesize = validdata.tellg();
    validdata.seekg(offset, ios::beg);

    reccount = filesize/sizeof(Allrecords);
    rec = new(Allrecords[reccount]);

    validdata.read((char*) &rec, filesize);

    for(int i = 0; i <reccount; i++)
    {
    switch(rec.Newdrecord.record_type)
    {
    case 'c':
    case 'C':
    case 'd':
    case 'D':
    case 'i':
    case 'I':
    case 'r':
    case 'R':
    sort_function1();
    default:;
    };

    Recommendation #1:
    switch(toupper(rec.Newdrecord.record_type))
    {
    case 'C': case 'D': case 'I': case 'R':
    sort_function();
    default:
    }

    Recommendation #2:
    const string record_types("CDIR");
    if (record_types.find(rec.Newdrecord.record_type)
    != string::npos)
    {
    sort_function();
    }

    Recommendation #3: (uses inheritance)
    record_ptrs->sort_record();
    validdata.close();
    sortfile.close();

    return 0;


    };


    --
    Thomas Matthews

    C++ newsgroup welcome message:
    http://www.slack.net/~shiva/welcome.txt
    C++ Faq: http://www.parashift.com/c++-faq-lite
    C Faq: http://www.eskimo.com/~scs/c-faq/top.html
    alt.comp.lang.learn.c-c++ faq:
    http://www.raos.demon.uk/acllc-c++/faq.html
    Other sites:
    http://www.josuttis.com -- C++ STL Library book
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

Short program 3
unions 2
built in types 4
read problem 6
type conversion 5
function error 6
Access violation error 10
Logical error/ whole program contained within. 4

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,053
Latest member
BrodieSola

Latest Threads

Top