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 gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Passing an array of structs

Status
Not open for further replies.

DerPflug

Programmer
Mar 28, 2002
153
US
I have a program that reads an inventory binary file, loads the part_id and offset (via the "index_fill" function)into an array called "index", sorts "index", and should print the whole binary file with the complete record associated with each part_id. I get an error when passing the "index" array to my sort routine.

I have the following declarations at the beginning of the program:
Code:
#define MAX 50
int index_fill(index_t index[], FILE *INV);
//fills array
/*index_t is a struct consisting of the part_id and the offset*/

Code:
index_t index[MAX];
//array of index structs
Code:
index_t sort_index(index_t idx_file[], int rec_count);
index_t idx_file[MAX];

In the main function:
/*"source" is the file pointer to the source file;
"index_fill" function fills the array "index" and returns the number of records read from the file */

Code:
num_of_recs = index_fill(index, source);
//this works fine
Code:
sort_index(index, num_of_recs);
//error occurs here

the sort_index routine:
Code:
index_t 
sort_index(index_t idx_file[],int rec_count)
{
	int i;

//ID_LENGTH is 7, rec_count came from index_fill
Code:
	qsort(idx_file, rec_count, ID_LENGTH, compare);

//for testing only, print to verify order
Code:
	for(i = 0; i < rec_count; i++)
            printf( &quot;%s\n&quot;, idx_file[i]);
//ERRORS HERE
Code:
	return 0;
}

I have realized while writing this that the array of structs could be passed with pointers but I'm alittle pressed for time to get that working properly. When I get to the printf in sort_index I get an &quot;unhandled error: access violation&quot; error. I'm writing this in MS Visual C++.

Thanks in advance.
 
It's hard to say for sure without seeing the complete code. In the future, try to post a complete, compilable code sample that demonstrates the problem.

However, how is ID_LENGTH derived? Whatever that value is, it should be equal to sizeof(index_t) when you pass it to qsort(). If that's not the problem, it would be interesting to see your compare routine.
Russ
bobbitts@hotmail.com
 
Sorry, I thought it might be a bit much for this forum. But here it is nonetheless:
Code:
// Index_Test.cpp : Defines the entry point for the console application.
//

#include &quot;stdafx.h&quot;
#include <stdlib.h> //for atoi
#include <stdio.h>
#include <string.h>
#include <conio.h> //for getch
#include <ctype.h> //for isalpha
#include <math.h>


#define MAX 50
#define ID_LENGTH 7

FILE *source,
	 *destination;

   typedef struct {
	int  month;
	int  day;
	int  year;
} date;

struct part_t {
	char  part_id[6+1];
	char  part_descr[20+1];
	double  unit_price;
	int  quan_onhand;
	int  reodr_pt;
	int reodr_qty;
	date reodr_date;
	int delete_flag;
};

struct index_t {
	char part_id[6 + 1];
	long recoffset;
};  //or }index[50] = {{&quot;\0&quot;, 0L}};

part_t partrecord;
void create_report(void);
int index_fill(index_t index[], FILE *INV);

//Functions
index_t index[MAX]; //array of index structs 
index_t sort_index(index_t idx_file[], int rec_count);
index_t idx_file[MAX];
int compare(const void *a, const void *b);

int main(int argc, char* argv[])
{
	FILE *inp, *outp; 

	char source_file[40],
		 dest_file[40];
	int num_of_recs;
	
	printf(&quot;\t\tThis will create a text file report from the inventory file.\n\n&quot;);
	printf(&quot;\t\tEnter the name of the source file with the .txt extension\n&quot;);
	printf(&quot;\t\tor type EXIT to leave > &quot;);
	scanf(&quot;%s&quot;, &source_file);
	fflush(stdin);
	while (strlen(source_file) > 40)
			{
				printf(&quot;\n\n\n\tThe filename you entered is too long.\n&quot;);
				printf(&quot;\tEnter it again with a max of 40 characters.&quot;);
				printf(&quot;\n\t> &quot;);
				scanf(&quot;%s&quot;, &source_file);
				fflush(stdin);
			}
			//add .txt extension if not there
	
	if (strcmp(source_file, &quot;EXIT&quot;) != 0)
	{
		while (!strstr(source_file, &quot;.txt&quot;))
		{
			strcat(source_file, &quot;.txt&quot;);
		}
		source = fopen(source_file, &quot;rb&quot;); //pointer that points to binary file
		if (source == NULL) //if there's an error go back to entry screen
		{
			printf(&quot;File Open Error&quot;);
			printf(&quot;\n\nThis file either does not exist or&quot;);
			printf(&quot; it was entered incorrectly.\n\n&quot;);
			//exit(EXIT_FAILURE);
		}
	}
	
   if (strcmp(source_file, &quot;EXIT&quot;) != 0)
   {  //main if begin
	 printf(&quot;\n\n&quot;);
	 printf(&quot;\t\tEnter the name of the destination file with the .dat\n&quot;);
	 printf(&quot;\t\textension or type EXIT to leave > &quot;);
	 scanf(&quot;%s&quot;, &dest_file);
	 fflush(stdin);
	 while (strlen(dest_file) > 40)
			{
				printf(&quot;\n\n\n\tThe filename you entered is too long.\n&quot;);
				printf(&quot;\tEnter it again with a max of 40 characters.&quot;);
				printf(&quot;\n\t> &quot;);
				scanf(&quot;%s&quot;, &dest_file);
				fflush(stdin);
			}
			//add .dat extension if not there
	 if (strcmp(dest_file, &quot;EXIT&quot;) != 0)
	 {
		 while (!strstr(dest_file, &quot;.dat&quot;))
		{
			strcat(dest_file, &quot;.dat&quot;);
		}

		destination = fopen(dest_file, &quot;w&quot;); //pointer that points to binary file
		if (destination == NULL) //if there's an error go back to entry screen
		{
			printf(&quot;File Open Error&quot;);
			printf(&quot;\n\nThis file either does not exist or&quot;);
			printf(&quot; it was entered incorrectly.\n\n&quot;);
			//exit(EXIT_FAILURE);
		}
	 }
   } //main if end
	//j = 0;
	if (strcmp(source_file, &quot;EXIT&quot;) != 0 && strcmp(dest_file, &quot;EXIT&quot;) != 0)
	{  	
		//index_fill(index, source);
		num_of_recs = index_fill(index, source);
		sort_index(index, num_of_recs);
		
		printf(&quot;You made it here.&quot;);
		system(&quot;cls&quot;);
	}
	
    fclose(source);
	return 0;
}

	/*
void
create_report(void)//char source[40], char destination[40])
{
	/*****************************************************************
	*This function reads the binary file and creates a text report file.
	*****************************************************************/
	
	
//}
int 
index_fill(index_t index[], FILE *INV) //array of index structs and pointer to filename
{
	//file should already be open at this point
	//open file once during program and leave open until end
	int REC_COUNT = 0,z;
	long recoffset;
	part_t partrec;
	rewind(INV);  //goes to top of file

	/*Now set recoffset to current pointer position */
	recoffset = ftell(INV); 
	fread(&partrec, sizeof(part_t), 1, INV); //initial read
	while(!feof(INV))
	{
		index[REC_COUNT].recoffset = recoffset;
		strcpy(index[REC_COUNT++].part_id, partrec.part_id);
		recoffset = ftell(INV);
		fread(&partrec, sizeof(part_t),1,INV);
	} //end while
	//code for sort on part id
	for(z=0; z < REC_COUNT; z++)
	{
		printf(&quot;\n%s  %d&quot;, index[z].part_id, index[z].recoffset);
	}
	return REC_COUNT;
}

index_t 
sort_index(index_t idx_file[],int rec_count)
{
	int i;

	qsort(idx_file, rec_count, ID_LENGTH, compare);
	for(i = 0; i < rec_count; i++)
      printf( &quot;%s\n&quot;, idx_file[i]);

	return idx_file[rec_count];
}

int
compare(const void *a, const void *b)
{
	return(strcmp((char *)a,(char *)b));
}
 
Didn't you get what I said about ID_LENGTH? You define it as 7, but it should actually be sizeof(index_t). I didn't look at the rest of your code, so that may not be the only problem.

BTW, even though it is written in a sort of C style, it uses C++-specific constructs (such as using index_t instead as struct index_t). I imagine that your compiler must be treating it as C++ as well, given the file name you're using. Is that what you want?
Russ
bobbitts@hotmail.com
 
It appears that isn't my only problem. I've been sending the entire struct to qsort, so it's probably confused as to how to sort it. I only need the part_id portion sorted. Yes, since we're running MS Visual C++ the C++ constructs are fine.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top