Why the code doesn't work the way I wanted ?

D

dreamcatcher

I wrote the following program which gets student id, and name, and
score, store them into a file,

use qsort() to sort the score, but seems when I wanted to inquire
specific student's info using id in inq(), i just never get what I
wanted, don't know why. thanx for point out my error.



#include <stdio.h>

#include <stdlib.h>

#include <conio.h>



// due to this program was orginally written under Visual C++

// in order for C compilers which do not support boolean type

// I have to define such

#define bool int

#define true 1

#define false 0



#define sizeOfArray(a) (sizeof(a)/sizeof(a[0]))



typedef struct tagLink {

int id;

char name[64];

int score;

}Link;



Link lnkArray[4];



void input(void) {

int i;

FILE *fp;



fp=fopen("data.dat","w+");

if(fp==NULL) {

fprintf(stderr,"fopen() in input()\n");

exit(1);

}



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



puts("<new input");

puts("= ID =");

scanf("%d",&lnkArray.id);

puts("= Name =");

scanf("%s",lnkArray.name);

puts("= Score =");

scanf("%d",&lnkArray.score);

puts("end of input>");



fwrite(&lnkArray,sizeof(Link),1,fp);



}



puts("## before sort ##");

for(i=0;i<4;++i)

printf("%d\t%s\t%d\n",lnkArray.id,lnkArray.name,l-
nkArray.score);



fclose(fp);

}



int cmpD(const void *s1,const void *s2) { // sort in decending order

return ((Link *)s2)->score-((Link *)s1)->score;

}



int cmpA(const void *s1,const void *s2) { // sort in
ascending order

return ((Link *)s1)->score-((Link *)s2)->score;

}



void output(void) {

int i;

FILE *fp;



fp=fopen("data.dat","rb");

if(fp==NULL) {

fprintf(stderr,"fopen() in output()\n");

exit(2);

}



for(i=0;i<4 && !feof(fp);++i)

fread(&lnkArray,sizeof(Link),1,fp);



qsort(lnkArray,sizeOfArray(lnkArray),sizeof(Link),cmpD);



puts("## after sort ##");

for(i=0;i<4;++i)

printf("%d\t%s\t%d\n",lnkArray.id,lnkArray.name,l-
nkArray.score);



fclose(fp);

}



FILE *inq(int id) {

FILE *fp;

Link *lnk;

bool exist=false;



fp=fopen("data.dat","rb");

if(fp==NULL) {

puts("fopen()");

exit(2);

}



while(!feof(fp)) {



lnk=(Link *)malloc(sizeof(Link));

if(lnk==NULL) {

puts("malloc()");

exit(1);

}



fread(lnk,sizeof(Link),1,fp);



if(lnk->id==id) {

exist=true;

break;

}

}

return exist?fp:NULL;

}



void inquire(void) {

int id;

FILE *fp;

Link *lnk;



lnk=(Link *)malloc(sizeof(Link));

if(lnk==NULL) {

puts("malloc()");

exit(3);

}



puts("enter id for inquire:");

scanf("%d",&id);



fp=inq(id);

if(fp==NULL) {

puts("no such record");

exit(4);

}



fread(lnk,sizeof(Link),1,fp);



printf("%d\t%s\t%d\n",lnk->id,lnk->name,lnk->score);



free(lnk);

fclose(fp);

}



int main(void)

{

input();

output();

inquire();



return 0;

}



//// HERE'S THE PROBLEM ////////////





<new input

= ID =

1 // first student id

= Name =

gary // name

= Score =

100 // score

end of input>

<new input

= ID =

2 // second student id

= Name =

benjamin // name

= Score =

65 // score

end of input>

<new input

= ID =

3 // third

= Name =

april

= Score =

78

end of input>

<new input

= ID =

4 // fourth

= Name =

jason

= Score =

89

end of input>

## before sort ##

1 gary 100

2 benjamin 65

3 april 78

4 jason 89

## after sort ##

1 gary 100

4 jason 89

3 april 78

2 benjamin 65

enter id for inquire:

3 // enter April's id, but below ...

4 jason 8 // this is not what I wanted
 
N

Nick Austin

I wrote the following program which gets student id, and name, and
score, store them into a file,

use qsort() to sort the score, but seems when I wanted to inquire
specific student's info using id in inq(), i just never get what I
wanted, don't know why. thanx for point out my error.

Better, but this code still doesn't compile! I had to modify
input() as follows:
void input(void) {
int i;
FILE *fp;

fp=fopen("data.dat","w+");
if(fp==NULL) {
fprintf(stderr,"fopen() in input()\n");
exit(1);
}

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

puts("<new input");
puts("= ID =");
scanf("%d",&lnkArray.id);

scanf("%d",&lnkArray.id);
puts("= Name =");
scanf("%s",lnkArray.name);

scanf("%s",lnkArray.name);
puts("= Score =");
scanf("%d",&lnkArray.score);

scanf("%d",&lnkArray.score);
puts("end of input>");

fwrite(&lnkArray,sizeof(Link),1,fp);

fwrite(&lnkArray,sizeof(Link),1,fp);
}

puts("## before sort ##");
for(i=0;i<4;++i)
printf("%d\t%s\t%d\n",lnkArray.id,lnkArray.name,lnkArray.score);

fclose(fp);
}

void inquire(void) {
int id;
FILE *fp;
Link *lnk;

lnk=(Link *)malloc(sizeof(Link));
if(lnk==NULL) {
puts("malloc()");
exit(3);
}

puts("enter id for inquire:");
scanf("%d",&id);

fp=inq(id);
if(fp==NULL) {
puts("no such record");
exit(4);
}

The problem here is that inq() has already read the record that
matches the id you wanted.
fread(lnk,sizeof(Link),1,fp);

This reads the record after the matching record.
printf("%d\t%s\t%d\n",lnk->id,lnk->name,lnk->score);

free(lnk);
fclose(fp);
}

Nick.
 
E

Emmanuel Delahaye

In 'comp.lang.c' said:
Better, but this code still doesn't compile! I had to modify
input() as follows:
scanf("%d",&lnkArray.id);

scanf("%d",&lnkArray.id);


This guy must be a troll, because we spend our time to correct his code, and
he continues to post the same errors...
 
D

dreamcatcher

i'm learning the language, so don't be so mad at a rookie. thanx for the
critics anyway. and I still don't know how to modify the code to get the
correct output.
 
P

pete

dreamcatcher said:
i'm learning the language, so don't be so mad at a rookie.
thanx for the critics anyway. and I still don't know how
to modify the code to get the correct output.

/* BEGIN new.c */

#include <stdio.h>
#include <stdlib.h>

#define LINKS 4

struct tagLink {
unsigned id;
char name[64];
unsigned score;
};

struct statusLink {
struct tagLink tag;
int status;
};

void input(char *, char *, size_t);
void output(char *, char *, size_t);
int cmpD(const void *, const void *);
struct statusLink inq(unsigned, char *, char *, size_t);
void inquire(char *, char *, size_t);

int main(void)
{
static char fn_write[] = "data.dat";
char *fn_read = fn_write;
char *mode_write = "wb", *mode_read = "rb";
size_t links = LINKS;

input(fn_write, mode_write, links);
output(fn_read, mode_read, links);
inquire(fn_read, mode_read, links);
return 0;
}

int cmpD(const void *s1,const void *s2)
{
return ((struct tagLink *)s2) -> score
> ((struct tagLink *)s1) -> score ? -1
: ((struct tagLink *)s1) -> score
> ((struct tagLink *)s2) -> score ;
}

void input(char *fn_write, char *mode_write, size_t links)
{
size_t i;
FILE *fp_write;
struct tagLink *lnkArray;

lnkArray = malloc(links * sizeof *lnkArray);
if (!lnkArray) {
fputs("malloc() in input()", stderr);
exit(EXIT_FAILURE);
}
fp_write = fopen(fn_write, mode_write);
if (fp_write == NULL) {
fputs("fopen() in input()", stderr);
exit(EXIT_FAILURE);
}
for (i = 0; links != i; ++i) {
puts("<new input");
puts("= ID =");
scanf("%u", &lnkArray.id);
puts("= Name =");
scanf("%s", lnkArray.name);
puts("= Score =");
scanf("%u", &lnkArray.score);
puts("end of input>");
fwrite(lnkArray + i, sizeof *lnkArray, 1, fp_write);
}
fclose(fp_write);
puts("## before sort ##");
for (i = 0; links != i; ++i) {
printf("%u %s %u\n",
lnkArray.id, lnkArray.name, lnkArray.score);
}
free(lnkArray);
}

void output(char *fn_read, char *mode_read, size_t links)
{
size_t i;
FILE *fp_read;
struct tagLink *lnkArray;

lnkArray = malloc(links * sizeof *lnkArray);
if (!lnkArray) {
fputs("malloc() in output()", stderr);
exit(EXIT_FAILURE);
}
fp_read = fopen(fn_read, mode_read);
if (fp_read == NULL) {
fputs("fopen() in output()\n", stderr);
exit(EXIT_FAILURE);
}
fread(lnkArray, links * sizeof *lnkArray, 1, fp_read);
fclose(fp_read);
qsort(lnkArray, links, sizeof *lnkArray, cmpD);
puts("## after sort ##");
for (i = 0; links != i; ++i) {
printf("%u %s %u\n",
lnkArray.id, lnkArray.name, lnkArray.score);
}
free(lnkArray);
}

struct statusLink
inq(unsigned id, char *fn_read, char *mode_read, size_t links)
{
unsigned i;
struct statusLink lnk;
FILE *fp_read;
struct tagLink *lnkArray;

lnkArray = malloc(links * sizeof *lnkArray);
if (!lnkArray) {
fputs("malloc() in inq()", stderr);
exit(EXIT_FAILURE);
}
fp_read = fopen(fn_read, mode_read);
if (fp_read == NULL) {
fputs("inq() fopen() failure\n", stderr);
exit(EXIT_FAILURE);
}
fread(lnkArray, links * sizeof *lnkArray, 1, fp_read);
fclose(fp_read);
lnk.status = 0;
for (i = 0; links != i; ++i) {
if (lnkArray.id == id) {
lnk.tag = lnkArray;
lnk.status = 1;
break;
}
}
free(lnkArray);
return lnk;
}

void inquire(char *fn_read, char *mode_read, size_t links)
{
unsigned id;
struct statusLink slnk;
struct tagLink lnk;

puts("enter id for inquire:");
scanf("%u", &id);
slnk = inq(id, fn_read, mode_read, links);
if (!slnk.status) {
puts("no such record");
} else {
lnk = slnk.tag;
printf("%u %s %u\n",
lnk.id, lnk.name, lnk.score);
}
}

/* END new.c */
 

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

Members online

No members online now.

Forum statistics

Threads
473,999
Messages
2,570,243
Members
46,836
Latest member
login dogas

Latest Threads

Top