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!

searching through a array of structures

Status
Not open for further replies.

tipdrill

Programmer
Oct 25, 2007
2
GB
I created a 2d array of structures thats reads a .txt file which has Iris data:
4.4 3.0 1.3 0.2 setosa
4.9 2.4 3.3 1.0 versicolor
4.9 2.5 4.5 1.7 virginica
5.0 3.2 1.2 0.2 setosa
5.0 3.5 1.3 0.3 setosa
5.0 3.6 1.4 0.2 setosa
5.0 3.3 1.4 0.2 setosa
5.0 3.4 1.5 0.2 setosa
5.0 3.0 1.6 0.2 setosa
i.e a set of floats and strings.
what I need to do is search through the array and record the number of different classes that exist...ie how many "setosa" are in the file.
here is the code... create a irisdata.txt with the data above and run the code

#include <stdio.h>
#include <stdlib.h>
#define DAT_MAX_LINES 150

struct mixed
{
float Plength;
float Pwidth;
float Slength;
float Swidth;
char Class[20];
};
/***************************************************************/
/*******count the number of classes in the data*****************/


int count_setosa(struct mixed array[DAT_MAX_LINES][5])
{
int i;
int r=0;
//int m=0;
//int p=0;

for(i=0;i<DAT_MAX_LINES;i++)
{
test = array[4].Class;
//printf("%s\n",array[4].Class);
while(array[4].Class == "setosa")
{
++r;
//printf("Number Setose present = %d\n", r);

/*else if (array[4].Class == "versicolor")
{
m++;
//printf("Number versicolor present = %d\n", m);
}
else if(array[4].Class == "virginica")
{
p++;
//printf("Number virginica present = %d\n", p);
}*/

}
}
return r;
}
int main(void)
{

struct mixed array[DAT_MAX_LINES][5];
int n = 0;
int i;
char ch;
int countr;

FILE * pRead = fopen("irisdata.txt", "r");

if (!pRead)
{
printf("File cannot be opened\n");
return EXIT_FAILURE;
}

printf("Contents of irisdata.txt:\n");

while ( (n < DAT_MAX_LINES) && (!feof(pRead)) )
{
fscanf(pRead,"%f%f%f%f%s\n", &array[n][0].Slength, &array[n][1].Swidth, &array[n][2].Plength, &array[n][3].Pwidth, &array[n][4].Class);
++n;

}


if ( (!feof(pRead)) && (n>DAT_MAX_LINES) )
{
printf("Error: file to large for array.\n");
}

fclose(pRead);

for (i = 0; i < n; ++i)
{
printf("%d: %f, %f, %f, %f ,%s\n", i, array[0].Slength, array[1].Swidth, array[2].Plength, array[3].Pwidth, array[4].Class);

}

countr = count_setosa(array);
printf("Number Setosa present = %d\n", countr);

ch = getchar();
return 0;
}
 
> [tt]struct mixed array[DAT_MAX_LINES][5];[/tt]
Why is this a 2D array?

> [tt]fscanf(pRead,"%f%f%f%f%s\n", &array[n][0].Slength, &array[n][1].Swidth, &array[n][2].Plength, &array[n][3].Pwidth, &array[n][4].Class);[/tt]
Your 5 fields are already captured by the field names of the structure, you don't need an extra array dimension as well.
Say
[tt]fscanf(pRead,"%f%f%f%f%s\n", &array[n].Slength, &array[n].Swidth, &array[n].Plength, &array[n].Pwidth, array[n].Class);[/tt]
Note the lack of & when scanning into a char array with the %s conversion.

> [tt]while ( (n < DAT_MAX_LINES) && (!feof(pRead)) )[/tt]
feof() can only be true when the fscanf() in the previous loop interation failed. But by then, n has already been incremented.

Input and conversion all in one (which is what fscanf is) can be very problematic to deal with if there is any variance in the data from what is expected. For that reason, I separate input from conversion, and deal with the different kind of fail states appropriately.
Code:
char buff[BUFSIZ];
while ( (n < DAT_MAX_LINES) &&
        (fgets( buff, sizeof buff, pRead) != NULL ) ) {
    if ( sscanf( buff, "%f%f%f%f%s", 
                 &array[n].Slength, &array[n].Swidth,
                 &array[n].Plength, &array[n].Pwidth,
                 array[n].Class ) == 5 ) {
        /* good data */
        n++;
    } else {
        /* bad data */
    }
}
Use [code][/code] tags when you post more code.

> while(array[4].Class == "setosa")
Use strcmp() in string.h to compare strings.
Eg.
[tt]while( strcmp( array.Class, "setosa" ) == 0 )[/tt]


--
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
 
Thanks didnt spot those errors, and yeah the strcmp works!!!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top