Help with newb's project

T

The_Kingpin

Hi all,

I'm new to C programming and looking for some help. I have a homework
project to do
and could use every tips, advises, code sample and references I can get.

Here's what I need to do. I have a file named books.txt that contains all
the informations
on the books. Each book is a struc containing 6 fields written on
separated line in the
folder. I need to use the fgetc command to read the info of this file.

The program must create 2 alphabetical order sorted by book's subject and
for a
same subject, the other info must be grouped by autor's name.

The second list must be created sorted in decreasing order of the book's
release date, and
for each year, the info must be grouped by subject.

Nos these two lists must also be created in another file named
booksort.txt. Each autor's
first and last name must be uniform (all lowercase except for the first
character). Also,
if a first name contains only 1 character, a '.' must follow (ie. Smith
Marc L.). If a
non-character is found ('-', ',', '.', etc.), we must replace it by a "/"
and add the
correct number of spaces (ie. Marc*Smith is now Marc / Smith)

Finaly, we must change the date's format from the current file (m/d/yyyy)
to (yyyy/mm/dd)


Looks like a lot of job to me so as I said, I'm tking anything that can
help me.
Thanks for your time and for helping a newb finding his way !

Frank
 
V

Vladimir Kadychevski

On Sat, 23 Oct 2004 18:33:50 -0400
hi there
i think it will be better for you to take a good C - programming book and try doing things by yourself. I don't think it would be very difficult for you to write this program. But if you want to become a programmer you have to learn how to find solutions by yourself ;) This is enen more true when the program to write is a part of your homework.

for a manual i think K&R is not a bad choice (have a look there is a thread in this group about the subject)

BTW i don't think comp.lang.c is here to do you your homework ;)
i think other people in this group will agree with my point of view ;)

try doing your exercise (write some algorithms and stuff) and if there is something you don't understand give me a sign :)

Vladimir

PS: The only advice i can give you at the moment is to start thinking by yourself :) and _understand_ what's the purpose of each line of code you are writing.
 
M

Malcolm

The_Kingpin said:
I'm new to C programming and looking for some help. I have a homework
project to do and could use every tips, advises, code sample and references
I can get.

Here's what I need to do. I have a file named books.txt that contains all
the informations on the books. Each book is a struc containing 6 fields
written on separated line in the folder. I need to use the fgetc command to
read the info of this file.
First a bit of terminology. A "struct" is a C construct that groups related
pieces of data in memory. A "record" is an entry in a database. Both records
and structs have "fields", but normally we would call a struct "field" a
member.

fgetc() reads a file a byte at a time. There may be a reason your tutor
wants you to use this function. Normally however one would use fgets() or
fscanf() for the task.
Reading a line into memory is relatively easy. The harder part is parsing
it. Your options are the scanf() family of functions, which have a format
string you need to learn to construct, strtok(), which will break up the
string into tokens for you, or roll your own using strtol(), strcpy(),
strcmp() and suchlike functions to break the line up.
You need to be aware that data files are sometimes corrupt, and reject any
malformed input.

Having extracted the six fields, you simply assign them to the relevant
members of the structure. So if you have title, author, price, publisher,
year of publication, and Library of Congress number you might have

struct book
{
char title[64];
char author[64];
char publisher[64];
double price;
int year;
struct LibCongId congress_id;
};

struct LibCongId would contain the subfields used to contain a Library of
Congress number.


One problem is that you don't know how many records are in the file until
you have parsed it. For this reason you need to use realloc() to expand your
list of books, so you can read in a file of any size.
The program must create 2 alphabetical order sorted by book's subject and
for a same subject, the other info must be grouped by autor's name.

The second list must be created sorted in decreasing order of the book's
release date, and for each year, the info must be grouped by subject.
So you need to call qsort() twice, once with the first comparison function,
output the data, and then with the second.
Nos these two lists must also be created in another file named
booksort.txt. Each autor's first and last name must be uniform (all lowercase
except for the first character). Also, if a first name contains only 1 character,
a '.' must follow (ie. Smith Marc L.). If a non-character is found ('-', ',', '.',
etc.), we must replace it by a "/" and add the correct number of spaces (ie.
Marc*Smith is now Marc / Smith)
This is a bit fiddly, and also wrong. Irish and Scottish names often don't
follow those rules. You need a function formatname(char *out, const char
*input)
Finaly, we must change the date's format from the current file (m/d/yyyy)
to (yyyy/mm/dd)
That's not too difficult. Store all dates internally in your own format,
then print them out as demanded.
Looks like a lot of job to me so as I said, I'm tking anything that can
help me.
Thanks for your time and for helping a newb finding his way !
Post your code if you have any real problems. It is quite a task for a first
program.
Start by defining your structure for the records, and then write a function
to read in one, like this

/*
reads a record
returns 0 on success, -1 for read error, -2 for line too long (etc)
*/
int readrecord(FILE *fp, struct book *out)

The read in the whole file, calling realloc() where necessary, and write a
test function to print it out to ensure it runs properly.
Then write the sorts.
Then write the output date, and then output your records.
Finally write the name formatting code, which will can be left until last.
If you can't do it at least you will have a 90% functional program.
 
C

CBFalconer

The_Kingpin said:
I'm new to C programming and looking for some help. I have a
homework project to do and could use every tips, advises, code
sample and references I can get.

Here's what I need to do. ... snip ...

Here's what you need to do: Listen to your lectures, read your
textbook, make a reasonable effort and then ask for help if you
haven't discovered enough yourself.

To have your homework done you must a) offer money b) supply your
instructors e-mail address for the submission and c) supply your
own real name and address. The money part will probably be covered
by USD 100 per hour, in advance.

As a free sample, here is a valid program that you can embellish:

#include <stdio.h>
int main(void) {return EOF == puts("Done");}

It has the minor bug of undefined behaviour on an i/o error.
 
J

Joe Wright

CBFalconer said:
Here's what you need to do: Listen to your lectures, read your
textbook, make a reasonable effort and then ask for help if you
haven't discovered enough yourself.

To have your homework done you must a) offer money b) supply your
instructors e-mail address for the submission and c) supply your
own real name and address. The money part will probably be covered
by USD 100 per hour, in advance.

As a free sample, here is a valid program that you can embellish:

#include <stdio.h>
int main(void) {return EOF == puts("Done");}

It has the minor bug of undefined behaviour on an i/o error.

`info libc` says puts() returns EOF on error. Your program's return
value is well defined it seems to me.

Cheapskate. I bid $105 an hour. ;)
 
O

osmium

:

I'm new to C programming and looking for some help. I have a homework
project to do
and could use every tips, advises, code sample and references I can get.

Here's what I need to do. I have a file named books.txt that contains all
the informations
on the books. Each book is a struc containing 6 fields written on
separated line in the
folder. I need to use the fgetc command to read the info of this file.

The program must create 2 alphabetical order sorted by book's subject and
for a
same subject, the other info must be grouped by autor's name.

The second list must be created sorted in decreasing order of the book's
release date, and
for each year, the info must be grouped by subject.

Nos these two lists must also be created in another file named
booksort.txt. Each autor's
first and last name must be uniform (all lowercase except for the first
character). Also,
if a first name contains only 1 character, a '.' must follow (ie. Smith
Marc L.). If a
non-character is found ('-', ',', '.', etc.), we must replace it by a "/"
and add the
correct number of spaces (ie. Marc*Smith is now Marc / Smith)

Finaly, we must change the date's format from the current file (m/d/yyyy)
to (yyyy/mm/dd)


Looks like a lot of job to me so as I said, I'm tking anything that can
help me.

Since you will have to do several sorts, you will want the data to be put
in an array of structures, but you don't know a priori how many elements the
array will have. So start by looking up qsort() and realloc(), both in
<stdlib.h>. I assume you are already familiar with malloc(). You will have
to write two or more compare functions to help qsort do its job. Lots of
people have already had trouble with qsort() so google groups should help
you if you need help.


Change the date to yyyymmdd as soon as possible (not last as you say above)
so the sorts can be performed in a sensible fashion. As someone has already
suggested, treat the name, insofar as possible, as a black box, this is a
time consuming fussy business and you may run out of time.

Are you sure you understand the instructions? I was confused by Smith Marc
L. From the text I would expect Smith M. You never tell us what the fields
are but I guessed differently than one of the other posters. My guess was

first name
last name
subject
mm
dd
yyyy

Your instructor won't expect much in the way of error handling so assume the
input file ( I assume he provides it) is valid.
 
T

The_Kingpin

Hi again all,

First I just want to clarify certain things: I didn't want somebody to
make it for me, maybe I wasn't clear. I just wanted some advices and
organization tips for each section. Thanks Malcolm, your suggestions were
really helpful.

Anyway I started making my main function which reads every struct objects
of a given file. To test it, I printed the results in the command window
of the project. Here's what it gives so far. Just want some feedback on
the way my function reads one line of the file and puts it in a new
struct's field: (I didnt found the rules as far as posting code, if anyone
can point it out if its not correct)

struct book
{
char title[80];
char autor[40];
char editor[20];
char ISBN[10];
char subject[20];
int release;
};
typedef struct book bookInfo;

int main()
{
char c[50]; /* Store read lines */
FILE *file; /* File pointer */
bookInfo *books; /* array of book */
int num_books = 0; /* keep count of number read in */
int i, j;

file = fopen("books.txt", "r");
if(file==NULL) {
printf("Error: can't open file.\n");
return 1;
}
else {
while(fgets(c, 50, file)!=NULL) {
/* keep looping until NULL pointer */
/* allocate memory dynamically for our books array */

if(num_books==0) {
books = calloc(1, sizeof(bookInfo));
}
else {
books = realloc(books, (num_books+1)*sizeof(bookInfo));
}


//Title Field
for(i=0, j=0 ; c!='\t' ; i++, j++) {
/* Loops until a tab character is reached */
books[num_books].title[j] = c;
}
/* Terminate string by adding a null character */
books[num_books].title[j] = '\0';


// Autor Field
for(i++, j=0 ; c!='\n'; i++, j++) {
/* Loops until a tab character is reached
books[num_books].autor[j] = c;
}
/* Terminate string by adding a null character *//
books[num_books].autor[j] = '\0';

// other struct's fields...
}

fclose(file); /* close file */
 
T

The_Kingpin

Hi again all,

First I just want to clarify certain things: I didn't want somebody to
make it for me, maybe I wasn't clear. I just wanted some advices and
organization tips for each section. Thanks Malcolm, your suggestions were
really helpful.

Anyway I started making my main function which reads every struct objects
of a given file. To test it, I printed the results in the command window
of the project. Here's what it gives so far. Just want some feedback on
the way my function reads one line of the file and puts it in a new
struct's field: (I didnt found the rules as far as posting code, if anyone
can point it out if its not correct)

struct book
{
char title[80];
char autor[40];
char editor[20];
char ISBN[10];
char subject[20];
int release;
};
typedef struct book bookInfo;

int main()
{
char c[50]; /* Store read lines */
FILE *file; /* File pointer */
bookInfo *books; /* array of book */
int num_books = 0; /* keep count of number read in */
int i, j;

file = fopen("books.txt", "r");
if(file==NULL) {
printf("Error: can't open file.\n");
return 1;
}
else {
while(fgets(c, 50, file)!=NULL) {
/* keep looping until NULL pointer */
/* allocate memory dynamically for our books array */

if(num_books==0) {
books = calloc(1, sizeof(bookInfo));
}
else {
books = realloc(books, (num_books+1)*sizeof(bookInfo));
}


//Title Field
for(i=0, j=0 ; c!='\t' ; i++, j++) {
/* Loops until a tab character is reached */
books[num_books].title[j] = c;
}
/* Terminate string by adding a null character */
books[num_books].title[j] = '\0';


// Autor Field
for(i++, j=0 ; c!='\n'; i++, j++) {
/* Loops until a tab character is reached
books[num_books].autor[j] = c;
}
/* Terminate string by adding a null character *//
books[num_books].autor[j] = '\0';

// other struct's fields...
}

fclose(file); /* close file */
 
M

Malcolm

Joe Wright said:
`info libc` says puts() returns EOF on error. Your program's return
value is well defined it seems to me.
However a return value of "true" from main() is not defined.
Cheapskate. I bid $105 an hour. ;)
You can get advice from some highly qualified people for absolutely free on
comp.lang.c, and certainly if a company decided to hire me out as a guru
then a hundred dollars (or about seventy quid) an hour wouldn't be too
unreasonable a figure.

The problem with "help me with my homework" requests is that you want the OP
to put in some effort, but simply writing some code not normally a good way
to approach a problem. He needs to break down the task into sections, and
plan the program. So the best time to get advice is at the beginning, before
you have written a single line.

Advice isn't the same thing as a homework doing service. Obviously most
homework problems are so simple that an experienced C programmer could just
sit down and write the thing straight off, but this isn't helpful. However
just saying "show me some code" isn't too helpful either.
 
K

Keith Thompson

CBFalconer said:
As a free sample, here is a valid program that you can embellish:

#include <stdio.h>
int main(void) {return EOF == puts("Done");}

It has the minor bug of undefined behaviour on an i/o error.

Executing "return 1;" from main returns an implementation-defined
status to the host environment; it doesn't invoke undefined behavior.
 
A

Al Bowers

The_Kingpin said:
Hi again all,
Anyway I started making my main function which reads every struct objects
of a given file. To test it, I printed the results in the command window
of the project. Here's what it gives so far. Just want some feedback on
the way my function reads one line of the file and puts it in a new
struct's field: (I didnt found the rules as far as posting code, if anyone
can point it out if its not correct)

The code appears ok but I have a few suggestions.
struct book
{
char title[80];
char autor[40];
char editor[20];
char ISBN[10];
Made this bigger.
char ISBN[20];
char subject[20];
int release;
};
typedef struct book bookInfo;

I would define another struct that has as members, one, a pointer
to the array of books, and, two, a member in which you keep a count
of the number of elements. Example:

typedef struct BOOKSET
{
bookInfo *book;
size_t num;
} BOOKSET;

Instead of putting all the code in function main, write seperate
functions that will manipulate the struct object. For example,
functions AddBook, PrintBookSet, FreeBookSet, etc.
int main()
{
char c[50]; /* Store read lines */

Make this bigger.
char c[200];
FILE *file; /* File pointer */
bookInfo *books; /* array of book */
int num_books = 0; /* keep count of number read in */
int i, j;

file = fopen("books.txt", "r");
if(file==NULL) {
printf("Error: can't open file.\n");
return 1;
}
else {
while(fgets(c, 50, file)!=NULL) {
/* keep looping until NULL pointer */
/* allocate memory dynamically for our books array */

if(num_books==0) {
books = calloc(1, sizeof(bookInfo));
}
else {
books = realloc(books, (num_books+1)*sizeof(bookInfo));
}

The if-else is not needed. Function realloc can handle all
allocations. See the code below for an example.
//Title Field
for(i=0, j=0 ; c!='\t' ; i++, j++) {
/* Loops until a tab character is reached */
books[num_books].title[j] = c;
}
/* Terminate string by adding a null character */
books[num_books].title[j] = '\0';


// Autor Field
for(i++, j=0 ; c!='\n'; i++, j++) {
/* Loops until a tab character is reached
books[num_books].autor[j] = c;
}
/* Terminate string by adding a null character *//
books[num_books].autor[j] = '\0';

// other struct's fields...


You might consider using sscanf to parse the line in the file.
}

fclose(file); /* close file */

Here is an example that uses the colon:)) as the delimiter.

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

struct BOOK
{
char title[80];
char autor[40];
char editor[20];
char ISBN[20];
char subject[20];
int release;
};

typedef struct BOOKSET
{
struct BOOK *book;
size_t num;
} BOOKSET;
/* Prototypes */
int AddBook(BOOKSET *p, char *s);
void PrintBook(struct BOOK *p);
void PrintBookSet(BOOKSET *p);
void FreeBOOKSET(BOOKSET *p);

int main(void)
{
char c1[] = "The New American Bible:IMPRIMATURE James Hickey:"
"World Publishing:052906484-7:Religion:5";
char c2[] = "Mastering Algorithms With C:Kyle Loudon:O'Reilly:"
"1-5652-453-3:progamming:2";
BOOKSET mylibrary = {NULL}; /* Empty bookshelf */

AddBook(&mylibrary,c1);
AddBook(&mylibrary,c2);
PrintBookSet(&mylibrary);
FreeBOOKSET(&mylibrary);
return 0;
}

int AddBook(BOOKSET *p, char *s)
{
struct BOOK *tmp;

if((tmp = realloc(p->book,(sizeof *p->book)*(p->num+1))) == NULL)
return 0;
p->book = tmp;
if(6 != sscanf(s,"%[^:]:%[^:]:%[^:]:%[^:]:%[^:]:%d",
p->book[p->num].title,p->book[p->num].autor,
p->book[p->num].editor,p->book[p->num].ISBN,
p->book[p->num].subject,&p->book[p->num].release))
return 0;
p->num++;
return 1;
}

void PrintBook(struct BOOK *p)
{
printf("Title: %s\n"
"Author: %s\n"
"Editor: %s\n"
"Subj: %s\n"
"ISBN: %s\n"
"Release: %d\n\n",p->title,p->autor,p->editor,
p->subject,p->ISBN,p->release);
return;
}

void PrintBookSet(BOOKSET *p)
{
size_t i;

for(i = 0; i < p->num;i++) PrintBook(&p->book);
return;
}

void FreeBOOKSET(BOOKSET *p)
{
free(p->book);
p->book = NULL;
p->num = 0;
}
 
J

Joe Wright

Malcolm said:
However a return value of "true" from main() is not defined.


You can get advice from some highly qualified people for absolutely free on
comp.lang.c, and certainly if a company decided to hire me out as a guru
then a hundred dollars (or about seventy quid) an hour wouldn't be too
unreasonable a figure.

The problem with "help me with my homework" requests is that you want the OP
to put in some effort, but simply writing some code not normally a good way
to approach a problem. He needs to break down the task into sections, and
plan the program. So the best time to get advice is at the beginning, before
you have written a single line.

Advice isn't the same thing as a homework doing service. Obviously most
homework problems are so simple that an experienced C programmer could just
sit down and write the thing straight off, but this isn't helpful. However
just saying "show me some code" isn't too helpful either.

That is a very nice, thoughtful and serious response to my note to
Chuck. I was being a little facetious. I'm sure most of us agree
with your sentiments above. I do.

Often, the poster would offer money for one or any of us to do the
homework. Although we delight in working for money, our clients are
not usually programming students asking for help cheating on their
exams. The 'student' poster might attract a bid from someone, "I'll
do it for $100" for example. The poster sees the 'bite' and assumes
others will under-bid the first one.

We don't. We bid it up. Each new bid is higher than the previous
one. None of us actually accept the offer (do we?) but simply
delight in the poster's confusion as bids go up beyond his means and
he finally realizes his foolishness.
 

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

Similar Threads

Need Help with Project 1
School Project 1
Help for my project in the last minute 0
Help 1
Please help 2
Help with code plsss 0
Please critique my code for fun learning project. 5
Help with code 0

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,904
Latest member
HealthyVisionsCBDPrice

Latest Threads

Top