Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

getting error on file read

Status
Not open for further replies.

ShawnCoutts

Programmer
Jul 4, 2006
74
CA
I am using the fgets() function to read from a file. I am fairly sure that this file is all stored on one line, but when I open it in notepad, its broken into several.

Anyways my problem is that on the second read from the file i am recieving this error:

"Access violation at address 7C901095 in module ntdll.dll. Write of address 400EBA70"

I am still unsure as to what is causing this error, i do know it has something to do with the code that is being executed after the read because if i comment out all that code the file is read just fine without any errors.

the code looks like this:
Code:
     while (fgets(in_buffer, 160, tap_file))
                {

                        StrLCopy(record_type, in_buffer, 2);
                        switch_key = static_cast<AnsiString>(record_type).ToInt();
                        record = static_cast<AnsiString>(in_buffer);

                        switch (switch_key)
                        {
                                case 10:
                                        HEADER *hrec;
                                        hrec = (HEADER *) malloc(sizeof(HEADER));
                                        sprintf(hrec->record_type, "%s", record.SubString(0,2));
                                        sprintf(hrec->sender, "%s%", record.SubString(3,5));
                                        sprintf(hrec->recipient, "%s", record.SubString(8,5));
                                        sprintf(hrec->file_seq_num, "%s", record.SubString(13,5));
                                        sprintf(hrec->tax_treatment, "%s", record.SubString(18,1));
                                        for(int i = 1; i <= 8; i++)
                                        {
                                                sprintf(hrec->tax_rate[i-1], "%s", record.SubString(((4*i)+15),3));
                                        }
                                        sprintf(hrec->file_create_date, "%s", record.SubString(64,6));
                                        sprintf(hrec->file_trans_date, "%s", record.SubString(70,6));
                                        sprintf(hrec->trans_cutoff_time, "%s", record.SubString(76,12));
                                        sprintf(hrec->utc_time_offset, "%s", record.SubString(88,5));
                                        sprintf(hrec->spec_ver_num, "%s", record.SubString(93,2));
                                        sprintf(hrec->international_access_code, "%s", record.SubString(95,12));
                                        sprintf(hrec->country_code, "%s", record.SubString(107,8));
                                        free(hrec);
                                        break;
                                case 12:
                                        EXCHANGE *erec;
                                        erec = (EXCHANGE *) malloc(sizeof(EXCHANGE));
                                        sprintf(erec->record_type, "%s", record.SubString(0,2));
                                        for(int i = 1; i <= 10; i++)
                                        {
                                                int z = (i - 1) * 12;
                                                char rate_info[12];
                                                char temp_buff[10];
                                                char temp_buff2[1];
                                                sprintf(rate_info, "%s", record.SubString((3+z),1));
                                                sprintf(temp_buff, "%s", record.SubString((4+z),10));
                                                sprintf(temp_buff2, "%s", record.SubString((14+z),1));
                                                strcat(rate_info,temp_buff);
                                                strcat(rate_info,temp_buff2);
                                                sprintf(erec->exchange_rate_table[i-1], "%s", rate_info);
                                        }
                                        free(erec);
                                        break;
                                case 14:
                                case 20:
                                case 30:
                                case 90:
                                break;
                        }
                        x = feof(tap_file);
                }

thanks in advance
 
OK, for some clarification before digging deeper:

You have a text file with a bunch of records stored in it. Each record is 159 characters long, and all records are on a single line. Is that correct? Or is each record 160 characters long? If records are 160 characters, you are losing a character from each record which then is prepended to the next record. fgets will only read 159 characters, since it needs space for the null terminator.

Also, probably not a source of your problem, but you have an extra % in the line:

Code:
sprintf(hrec->sender, "%s%", record.SubString(3,5));
 
each record is 160 characters in length. i was unaware that fgets actually did infact need space to put the null byte. It doesnt make any difference anyway, as the last 6 characters or so are never used. And yes all records are stored on the same line. and the extra % that was hidden in there, was not affecting my code any.

Thanks
 
It doesnt make any difference anyway, as the last 6 characters or so are never used.

However your second read doesn't begin reading at character 161, but at character 160 (the final character of the first record) which means your second read doesn't correctly read the second record.

If you're getting the access violation right at your second fgets, rather than in your processing after, something in your processing is messing with your pointers. Trace through and watch what happens to tap_file and in_buffer.

If the error isn't actually happening right at the fgets, then trace through & see exactly where it is happening.

Also, I'm assuming that in_buffer is at least 161 characters in length and that each element of hrec is large enough to receive each corresponding substring (i.e. record_type is length 3, sender is length 6 etc).

There's still some unknowns in the code you posted, so if you still can't get it, post your struct definitions (HEADER and EXCHANGE) and your other variable definitions and some sample record data from your input file.

good luck.
 
I managed to solve my problems. I changed the way that my code worked. Instead of having the function do all the reads in one call, the function call is setup in a while loop, and i just use fseek to set the file pointer to the correct location.

Thanks for all of your help. I was having some minor problems with my memory locations being 1 short, but that has all been fixed as well

Thanks again
 
Hi

If your file was a text ascii only file then read on...

I used to open files and read in the buffers and all that stuff but if it is an ascii file I find that the following is far easier to use..

TStringList *FL = new TStringList();
int f = 0;

FL->Clear();
FL->LoadFromFile(FileName); // FileName = your text file

while ( f < FL->Count )
{
AnsiString Record = FL->Strings[f];
// Now do any processing on Record.
f++;
}
delete FL;

Just a thought..


Hope this helps!

Regards

BuilderSpec
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top