Thread: Structure Array Searching help ~

1. Structure Array Searching help ~

First lets view the question...

Write a program to manage a database of information about an individual Compact Disc (CD) collection. Each entry includes the name of the group, the name of the CD, the year it was released, the price paid for it, and the total playing time.

• Allow the user to search for all the CDs released by a given group. Your program should able to display the CD detail based on the group name entered by the user.
• Allow the user to print aggregate information: the total cost of the collection.

__________________________________________________ __________________________________________________ ________________________

My coding so far...

Code:
```#include <stdio.h>
#include <string.h>
#define NUM_CDS 100 // 100 hard-coded

struct CD {
char group_name[40];
char cd_name[40];
int year;
double price;
double playing_time;
}

main(void) {

int i, counter = 0;
char req_group[100];
char digimon[] = {0};

struct CD digimon[NUM_CDS];
strcpy(digimon[NUM_CDS].group_name, "Digimon");
strcpy(digimon[NUM_CDS].cd_name, "Digimon");
digimon[NUM_CDS].year = 1999;
digimon[NUM_CDS].price = 25.5;
digimon[NUM_CDS].playing_time = 25.5;
printf("Group Name: %s\nCD Name: %s\nYear: %d\nPrice: %.2lf\nPlaying Time: %.2lf",
digimon[NUM_CDS].group_name, digimon[NUM_CDS].cd_name, digimon[NUM_CDS].year, digimon[NUM_CDS].price, digimon[NUM_CDS].playing_time);

printf("Which cd you wish? ");
gets(req_group);

for(i=0;i<NUM_CDS;i++){

if( strcmp( digimons[i].group_name, req_group) == 0 )
}

return 0;
}```
__________________________________________________ __________________________________________________ ________________________
Can someone guide me how to search the structure? And also what mean by print aggregate information? How can I print that? Very thanks you.

2. Code:
```\$ gcc -Wall search.c
search.c:13: warning: return type of ‘main’ is not ‘int’
search.c: In function ‘main’:
search.c:19: error: conflicting types for ‘digimon’
search.c:17: note: previous definition of ‘digimon’ was here
search.c:33: error: ‘digimons’ undeclared (first use in this function)
search.c:33: error: (Each undeclared identifier is reported only once
search.c:33: error: for each function it appears in.)
search.c:34: error: expected expression before ‘}’ token
search.c:37: error: incompatible types when returning type ‘int’ but ‘struct CD’ was expected
search.c:15: warning: unused variable ‘counter’```
Line 13: You need a semicolon after your struct definition, otherwise it thinks that's the return type for main. The correct form is int main(void). Read this.
Line 17/19: Only one variable can be named digimon. I think you want to ditch the char array on line 17.
Line 33: You spelled it wrong. There is no 's' on the end.
Line 34: You need a body for the if statement, but presumably that's what your question about searching is
Line 37: This will be fixed by fixing the issues for line 13.
Line 15: Ditch it if you're not going to use it.

I fixed all that, then got the following:
Code:
```\$ gcc -Wall search.c
/tmp/cchpaQJR.o: In function `main':
/home/charlesg/sandbox/test/search.c:28: warning: the `gets' function is dangerous and should not be used.```
Don't use gets. Read why here: Cprogramming.com FAQ > Why gets() is bad / Buffer Overflows. Use fgets instead.

As for your search, you're on the right track:
Code:
```for(i=0;i<NUM_CDS;i++){
if( strcmp( digimon[i].group_name, req_group) == 0 )
printf("I found what you wanted!\n");
}

// better if you need to do something when you don't find it:

for(i=0;i<NUM_CDS;i++){
if( strcmp( digimon[i].group_name, req_group) == 0 )
break;  // exit the loop early if we found it
}
if (i < NUM_CDS) {
// we found it
printf("I found what you wanted!\n");
}
else {
// we didn't find it
printf("Sorry, I couldn't find it.\n");
}```
EDIT: Just re-read your post. By aggregate information, it looks like your assignment wants the sum of the cost of all CD's in the group. Instead of printing you found it, add the price of that item (access that struct's price field) to a sum variable. When you're done with the loop, just print out the total price.

3. In C, arrays always start with an index of 0, not 1. So this is an error, since the highest array index would be NUM_CDS - 1.
Code:
`digimon[NUM_CDS].year = 1999;`
You could do a simple sequential search. Maybe find all the groups with years > 1999:
Code:
```for(i=0;i<NUM_CDS;i++) {
if(digimon[i].year >1999) {
printf("Name: %s\n",digimon[i].group_name);
printf("Year: %d\n", digimon[i].year);
}
}```
Welcome to the forum, Siaw! Using code tags on your first post ---> impressive!

4. Could not find?

After make the correction from all people suggest. Now my updated code in below...
__________________________________________________ _______
Code:
```#include <stdio.h>
#include <string.h>
#define NUM_CDS 100 // 100 hard-coded

struct CD {
char group_name[40];
char cd_name[40];
int year;
double price;
double playing_time;
} ;

int main(void){

int i;
char req_group[100];

struct CD digimon[NUM_CDS];
strcpy(digimon[NUM_CDS].group_name, "Digimon");
strcpy(digimon[NUM_CDS].cd_name, "Digimon");
digimon[NUM_CDS].year = 1999;
digimon[NUM_CDS].price = 25.5;
digimon[NUM_CDS].playing_time = 25.5;
printf("Group Name: %s\nCD Name: %s\nYear: %d\nPrice: %.2lf\nPlaying Time: %.2lf",
digimon[NUM_CDS].group_name, digimon[NUM_CDS].cd_name, digimon[NUM_CDS].year, digimon[NUM_CDS].price, digimon[NUM_CDS].playing_time);

printf("\n\nWhich cd you wish? ");
scanf("%[^\n]", req_group);

for(i=0;i<NUM_CDS;i++){

if( strcmp( digimon[i].group_name, req_group) == 0 )
printf("I found what you wanted!\n");
}

for(i=0;i<NUM_CDS;i++){
if( strcmp( digimon[i].group_name, req_group) == 0 )
break;  // exit the loop early if we found it
}

if (i < NUM_CDS) {
// we found it
printf("I found what you wanted!\n");
}

else {
// we didn't find it
printf("Sorry, I couldn't find it.\n");
}

return 0;
}```
__________________________________________________ _____

But now I face another problem is when I input the group name its still say could not found. Why? Note that I can't use fgets yet because my school haven teach us use fgets yet. Also how can I edit my code so that the info about digimon album will only display when search complete instead of like now it display immediately.

In C, arrays always start with an index of 0, not 1. So this is an error, since the highest array index would be NUM_CDS - 1.
Code:
`digimon[NUM_CDS].year = 1999;`
You could do a simple sequential search. Maybe find all the groups with years > 1999:
Code:
```for(i=0;i<NUM_CDS;i++) {
if(digimon[i].year >1999) {
printf("Name: %s\n",digimon[i].group_name);
printf("Year: %d\n", digimon[i].year);
}
}```
Welcome to the forum, Siaw! Using code tags on your first post ---> impressive!
Thanks for your welcome ^^ I study html before so I also know that how to use the code tag and its also important to view forum rules before post anything ~

6. Originally Posted by Siaw
First lets view the question...

Write a program to manage a database of information about an individual Compact Disc (CD) collection. Each entry includes the name of the group, the name of the CD, the year it was released, the price paid for it, and the total playing time.

• Allow the user to search for all the CDs released by a given group. Your program should able to display the CD detail based on the group name entered by the user.
• Allow the user to print aggregate information: the total cost of the collection.

Can someone guide me how to search the structure? And also what mean by print aggregate information? How can I print that? Very thanks you.
Before you start pounding code, only to frustrate the heck out of yourself you need to make a few decisions...

1) How is this information acquired?
2) How is it to be stored on disk?
3) How is it to be accessed from disk?

Ok... so there are 100 cds ...
Did they provide you with a disk file for the exercise?
If so, exactly what is in that file?

Do you have to create your own file?
if so...Exactly how are you going to store the information?

Based upon the struct...
This looks to me like an excellent application for random access binary files.
Do you know how they work?

You are a long long ways from writing code at this point. You need to sit down and analyse the job until you understand it well enough to do it on paper, by hand... then you need to plan out how you're going to code what you did manually... then you can start coding and testing....

Really you need to think this through....

7. You can NEVER use this:
Code:
`digimon[NUM_CDS].year = 1999;`
Because your highest array index is NUM_CDS - 1.

That's why this works, btw:
Code:
`for(i = 0;i < NUM_CDS; i++)  // <<-- Good! Standard idiom in C`
Code:
`for(i = 0;i <= NUM_CDS; i++) // <<--goes out of array's highest index`
as the first line of a for loop.

So, your assignment of data outside the bounds of the array, sent your data to -- somewhere outside the array. So naturally, your search wouldn't find the data. Accessing outside your array, is a great way to crash your program, also.

Code:
```#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NUM_CDS 100 // 100 hard-coded

struct CD {
char group_name[40];
char cd_name[40];
int year;
double price;
double playing_time;
} ;

int main(void){

int i, totalcd;
char req_group[NUM_CDS];

struct CD digimon[NUM_CDS];
strcpy(digimon[NUM_CDS].group_name, "Digimon");
strcpy(digimon[NUM_CDS].cd_name, "Digimon");
digimon[NUM_CDS].year = 1999;
digimon[NUM_CDS].price = 25.5;
digimon[NUM_CDS].playing_time = 25.5;
printf("Group Name: %s\nCD Name: %s\nYear: %d\nPrice: %.2lf\nPlaying Time: %.2lf",
digimon[NUM_CDS].group_name, digimon[NUM_CDS].cd_name, digimon[NUM_CDS].year, digimon[NUM_CDS].price, digimon[NUM_CDS].playing_time);

printf("\n\nEnter number of cd to search:");
scanf("%d",&totalcd);
gets(req_group); // just ignoring the unwanted "enter"

printf("\nWhich cd you wish? ");
gets(req_group);

for(i=0;i<totalcd;i++){

if(strcmp(req_group,digimon[i].group_name) == 0 ) {
// we found it
printf("I found what you wanted!\n");
}

else {
// we didn't find it
printf("Sorry, I couldn't find it.\n");
}
}

return 0;
}```

9. As was explained to you before, you are creating an array with 100 elements... these elements are numbered from 0 to 99 ... there is no array element #100 and when you store stuff there you are using memory you don't own... Even if you enter 100 for totalcd, the search is going to go from 0 to 99... because that's what the loop does... it exits when i = totalcd.

You need to read up on arrays and their correct usage in what ever textbooks or tutorials you own.
And... you need to listen to what people are telling you.

10. Thanks you for telling me and I also understand what you mean but I still don't know how to change my codes so that I can search successfully? May you give me some recommendation?
Originally Posted by CommonTater
As was explained to you before, you are creating an array with 100 elements... these elements are numbered from 0 to 99 ... there is no array element #100 and when you store stuff there you are using memory you don't own... Even if you enter 100 for totalcd, the search is going to go from 0 to 99... because that's what the loop does... it exits when i = totalcd.

You need to read up on arrays and their correct usage in what ever textbooks or tutorials you own.
And... you need to listen to what people are telling you.

11. Ok ~ I have made some change to my code. But the problem still remain...so any suggestion? My code in below ....

Code:
```#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct CD {
char group_name[50];
char cd_name[50];
int year;
double price;
double playing_time;
} ;

int main(void){

int i, cd_qty, found;
char req_group[50];

struct CD digimon[50];
strcpy(digimon[49].group_name, "Digimon");
strcpy(digimon[49].cd_name, "Digimon");
digimon[49].year = 1999;
digimon[49].price = 25.5;
digimon[49].playing_time = 25.5;
printf("Group Name: %s\nCD Name: %s\nYear: %d\nPrice: %.2lf\nPlaying Time: %.2lf",
digimon[49].group_name, digimon[49].cd_name, digimon[49].year, digimon[49].price, digimon[49].playing_time);

printf("\n\nHow many cd you wish? ");
scanf("%d",&cd_qty);
fflush(stdin);

printf("\nWhich cd you wish? ");
gets(req_group);

found = 0;

for(i=0;i<cd_qty;i++){

if(strcmp(digimon[i].group_name, req_group) == 0) {
// we found it
found = 1;
}
}

if (found == 1)
{
printf("I found what you wanted!\n");
}
else
{
printf("Sorry, I couldn't find it.\n");
}

return 0;

}```

12. Look at your search function...

You are asking how many cds a user wants (to find?)
Then you are limiting your array search to that number.

Now think carefully if the array holds 50 records and the user enters 3... how many records does your search look at?

Also the gets() function used to enter the group's name *includes the <enter> key* ... so you enter "fred" your buffer contains fred\n which isn't going to match the name in the struct. So you have to test for and remove the newline before your search will succeed.

13. Very thanks you ~ I finally solve the the searching problem. But now I need to display all the details of the search items after the users has search. I know I has already display it when this program start but I want to display it only if the user search this group names. So how can I display that?

My coding so far....
Code:
```#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct CD {
char group_name[49];
char cd_name[49];
int year;
double price;
double playing_time;
} ;

int main(void){

int i, found, cd_qty;
char req_group[50];

struct CD digimon[50];
strcpy(digimon[49].group_name, "Digimon");
strcpy(digimon[49].cd_name, "Digimon");
digimon[49].year = 1999;
digimon[49].price = 25.5;
digimon[49].playing_time = 25.5;
printf("Group Name: %s\nCD Name: %s\nYear: %d\nPrice: %.2lf\nPlaying Time: %.2lf",
digimon[49].group_name, digimon[49].cd_name, digimon[49].year, digimon[49].price, digimon[49].playing_time);

printf("\n\nHow many cd you wish? ");
scanf("%d",&cd_qty);
fflush(stdin);

printf("\nWhich cd you wish? ");
gets(req_group);

found = 0;
cd_qty = 50;

for(i=0;i<cd_qty;i++){

if(strcmp(digimon[i].group_name, req_group) == 0) {
// we found it
found = 1;
break;
}
}

if (found == 1)
{
printf("I found what you wanted!\n");

}
else
{
printf("Sorry, I couldn't find it.\n");
}

return 0;

}```

14. I have change some of my code... so how can I display all information related to digimon if the users search Digimon?

Code:
```#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct CD {
char group_name[49];
char cd_name[49];
int year;
double price;
double playing_time;
} Collection;

int main(void){

Collection digimon[3] = {
{"Digimon","Digimon", 1999, 25.5, 25.5 },
{"Pokemon","Digimon", 1999, 25.5, 25.5 },
{"Dragon","Digimon", 1999, 25.5, 25.5 }
};

int i, found, cd_qty;
char req_group[50];

printf("\n\nHow many cd you wish? ");
scanf("%d",&cd_qty);
fflush(stdin);

printf("\nWhich cd you wish? ");
gets(req_group);

found = 0;
cd_qty = 50;

for(i=0;i<cd_qty;i++){

if(strcmp(digimon[i].group_name, req_group) == 0) {
// we found it
found = 1;
break;
}
}

if (found == 1)
{
printf("I found what you wanted!\n");

}
else
{
printf("Sorry, I couldn't find it.\n");
}

return 0;

}```

15. My newest code is here....I could now display customer search result but, when the customer input search 2 cd at the same time then input 2 cd names, the result only display 1 cd info. How can I display 2 cd info after customer input 2 cd names?
Code:
```#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct CD {
char group_name[49];
char cd_name[49];
int year;
double price;
double playing_time;
} Collection;

int main(void){

Collection digimon[3] = {
{"Digimon","Digimon", 1999, 25.5, 25.5 },
{"Pokemon","Pokemon", 1999, 25.5, 25.5 },
{"Dragon","Dragon", 1999, 25.5, 25.5 }
};

int i, found, cd_qty;
char req_group[50];

printf("\n\nHow many cd you wish to search? ");
scanf("%d",&cd_qty);
fflush(stdin);

for(i=0;i<cd_qty;i++){
printf("\nName of the cd? ");
gets(req_group);
}

found = 0;
cd_qty = 50;

for(i=0;i<cd_qty;i++){

if(strcmp(digimon[i].group_name, req_group) == 0) {
// we found it
found = 1;
break;
}
}

if (found == 1)
{
printf("I found what you wanted!\n");
printf("Group Name: %s\nCD Name: %s\nYear: %d\nPrice: %.2lf\nPlaying Time: %.2lf",
digimon[i].group_name, digimon[i].cd_name, digimon[i].year, digimon[i].price, digimon[i].playing_time);
}

else
{
printf("Sorry, I couldn't find it.\n");
}

return 0;

}```