Adak 419 Nearly a Posting Virtuoso

What have you tried?

With linked lists, it's best to study it, and have a good sample program that you know works, to refer to while you are troubleshooting your own program.

I would either refer to your class/book notes on it for this, or grab a none good program from the net, and have it close at hand. Study it, to confirm that your idea of how it should work, corresponds correctly with the known good program.

Linked lists are a bit of a pain to just create out of thin air, if you're new to them, and have nothing to study in the way of good working code, first.

Adak 419 Nearly a Posting Virtuoso

Ah! OK, well, obviously in a while loop:

i=0;
while(1) {
   if(fread(&myArrayName[i++], sizeOfYourRecord, 1, FILE *pointer) < 2) 
     break;  //fread returns the number of record members it stored)
}
ÜÜÜÜÜÜÜ
 ÝfreadÞ   Reads data from a stream.
 ßßßßßßß

 Syntax:
   size_t fread(void *ptr, size_t size, size_t n, FILE *stream);

 Prototype in:
 stdio.h

 Remarks:
fread reads n items of data, each of length
size bytes, from the given input stream into a
block pointed to by ptr.

The total number of bytes read is (n x size).

 Return Value:
On successful completion, fread returns the
number of items (not bytes) actually read.

It returns a short count (possibly 0) on
end-of-file or error.

 Portability:
fread is available on all UNIX systems and is
defined in ANSI C.

 See Also:
  fopen    fwrite    printf    read

 Example:
 #include <string.h>
 #include <stdio.h>

 int main(void)
 {
    FILE *stream;
    char msg[] = "this is a test";
    char buf[20];

    if ((stream = fopen("DUMMY.FIL", "w+"))
        == NULL)
    {
       fprintf(stderr, "Cannot open output file.\n");
       return 1;
    }

    /* write some data to the file */
    fwrite(msg, strlen(msg)+1, 1, stream);

    /* seek to the beginning of the file */
    fseek(stream, SEEK_SET, 0);

    /* read the data and display it */
    fread(buf, strlen(msg)+1, 1, stream);
    printf("%s\n", buf);

    fclose(stream);
    return 0;
 }
Adak 419 Nearly a Posting Virtuoso

fread() to read binary records
fwrite() to write binary records

Want an example of fread()?

Back in a sec.

Adak 419 Nearly a Posting Virtuoso

So the struct will need two members, something like:

struct mystruct {
  char name[20];
  char passwrd[10];
}

Before main(), then in main(), create the struct itself:

struct mystruct mine[20];

and now you have an array of twenty records. Pass mine around like any other array, to your other functions, and remember, at that point, mine is a pointer, not a full array (but you can modify it's members that way).

Adak 419 Nearly a Posting Virtuoso

Did you try SENDING the data at slower speed? ;)

I want you to brush up on your Win32 serial communications, here:
http://msdn.microsoft.com/en-us/library/ms810467

and be sure to download the sample program that is linked right below the top paragraphs.

Run that sample, and see if it runs OK. What I want to confirm is that:

1) your hardware is OK. If you're going from one computer's serial port to another's, you need a cross over cable - not a straight through serial cable.

2) A known good program, will run on your system, correctly.

If #1 and #2 are OK, then we know that the system and the cable/serial port, are working properly, and start narrowing down the suspects in your program.

Unfortunately, serial communication has changed hugely since DOS days, and while some serial programs will still work, others simply will not.

Adak 419 Nearly a Posting Virtuoso

Each student will typically be taking several courses each semester, so adding more classes into your student struct, would not be unreasonable.

Two other alternatives:

1) Add a classes struct, and nest it inside your student struct.

The one I like best is an array of char, where each class is listed by it's abbreviation (standardized), and it's course number: so BIO110 refers to Biology 110, PHY212 to Physics 212, etc.

Now every class has exactly 6 char's (maybe you want 7 or 8 for some schools), and by simple division, you easily have the number of classes, and finding any class within this string for a database, would be easy.

I believe you're working toward this, are you not?

Joey_Brown commented: Adak, youve gave me a great idea m8! Thank you +1
Adak 419 Nearly a Posting Virtuoso

Ok, what have you tried to troubleshoot this?

Have you tried sending the data at slower speed? That would be my first test.

Adak 419 Nearly a Posting Virtuoso

So your logic needs to consider the lowest number first, and then continue adding the lowest number, until it's >= 5. If it's == 5 then print it.

Then you pop off the next number from the stack, and having backtracked to one for the second number, trying adding more one's until it's >=5, printing it if it's == 5.

The best way to kick-start your logic on a problem, is to keep working with the problem, keep seeing the resulting answers, and keep doing it by hand. Naturally, use your class notes as well, because you want to do this as much like your instructor wants, as possible.

Get clear on whether stack means using a data stack (a linked list or small array, as a stack), or if it means using the stack memory as a stack, in your program, by calling subordinate functions (and returning from them).

Adak 419 Nearly a Posting Virtuoso

You made an array with only 1 row, 1 column, and 1 depth.

Since arrays in C always begin with subscript 0, trying to refer to [1] in any dimension, is junk - you're out of bounds. ;)

Adak 419 Nearly a Posting Virtuoso

I'm thinking databases are not the topic for relative newcomers to take on.

Why don't you Google MySql and see if that meets your needs? It's open source, and there's a ton of info on the net regarding it's usage.

Adak 419 Nearly a Posting Virtuoso

The best way to simplify a program, is to refer back to your logic you used to create it. That might be your flowchart or pseudo code - or just a diagram on a napkin. Whatever you used to create the logic for this program.

Now ask yourself, "Are there any steps that could easily be combined?", "Do I have any steps that are redundant or unnecessary?".

Before you reach the ability to simplify a solution, you have to go past the understanding you had, when you created the more complicated solution. That seems backwards maybe, but it's true.

First thing, is to be absolutely certain you know what you want in your program. Your first post sounds unsure about 8 or 16 bit encryption. Nail down EXACTLY what you want, and run a small sample through the encryption you want, by hand - with paper and pencil - to be sure you understand it, and the steps for your logic and program, all make sense.

After the above, step through your program with the debugger, and watch the variables as they change. Are they changing as you need them to? Add any print statements you need into the code, but your debugger is your main helper, of course.

Good luck.

Adak 419 Nearly a Posting Virtuoso

Playoffs? sorry I am not living in America..is this football?

So if you have an index number of say a site how do you then get this information of the site in the struct so you could say print it or alter it? if that makes sense?

Yes, American football. ;) It's the kind of football where you don't fall asleep watching it on the TV. <lol>

You get the index number by a return, from find_site. Say I want to delete a site - not any site, of course. Just one site. So I need the index number of the site I want to delete.

I call find_site() and it looks for the site. If it's found, find_site() returns the index number to the site. Now I call delete_site(), and make the assignment to name that deletes that site (actually, I will re-use that index number, but that's later on, and with new data).

If find_site() can't find the site, then it returns 0. That's how it's normally done.

Adak 419 Nearly a Posting Virtuoso

The Aussie's and their Ant clusters:
http://cellar.org/showthread.php?t=24345

Adak 419 Nearly a Posting Virtuoso

Double your getchar()'s, and all will be well.

When you enter a char, you hit the the enter key, putting a newline ('\n') char into the keyboard stream (stdin). The first getchar() pulls off only the char you pressed BEFORE you hit enter, leaving the newline behind - and lets it get picked up by the next getchar().

You enter: 'A', but stdin has: 'A''\n', and that's your problem.

ch=getchar();
getchar();  //add this line

solves the problem.

Adak 419 Nearly a Posting Virtuoso

If there's a question about your program, post it up.

Busy (playoffs) weekend! ;)

Adak 419 Nearly a Posting Virtuoso

There's nothing wrong with your code - runs fine. There are some good C IDE's (integrated development environments), with editors, help buttons, and messages from the compiler and linker, and debugger.

Visual Express from Microsoft is one, and Code::Blocks is very good, as well, although it's separate from the compiler. Why not Google one up and give it a shot? Bound to be more productive.

Adak 419 Nearly a Posting Virtuoso

Not quite.

Before you can delete a record, you have to find out what the index number for that record is.

So when delete a record is called from the menu, you need to first call find_sites(), and return the index number to menu(), then call delete_site() and do the actual "deletion", there.

The return from find_sites() should be either:
* the index number of the record, if found

or

* zero, indicating that the record was not found

if((OK=find_site(whatever)) > 0) 
 //site was found and OK is the index number

Similar to that.
Of course, you're not actually deleting a record, you've just nullifying it with a simple assignment of one char to the name field. The efficiency is a plus, to the simplicity.

As always, you change a record in the array, and then write out the entire array to the file. You can change a record on the file itself, but that involves more file handling, and usually is hazardous to the data, for beginners to attempt.

Adak 419 Nearly a Posting Virtuoso

The device you're working with, only works from top line to bottom line (unless you do some repositioning of the cursor, which is not needed here).

print the top line of *'s

in a loop:
print the left side * print the spaces needed, then print the right side *
continue printing the above sides of the rectangle, until you've reached the
full height of the diagram.
end loop

Now print the bottom line of *'s.

That is your pseudo code logic. The empty space inside the rectangle is the width of the rectangle - 2, of course.

Give that a shot! ;)

Adak 419 Nearly a Posting Virtuoso

Sorry I posted my previous post before I saw the code you had posted.... somehow I don't know.

The program compiled with no errors or warnings and ran perfectly :-). The delete_site function deletes only the name of the site, but I thought this '\0' character would cause the whole line not to show. So do I have to strcmp() for the place as well? How do I compare integers? Or is there an easier way to do this?

Running "perfectly" is a good start! ;)

If you are printing out the name and place, as strings, then '\0' in the first char's place, will cause nothing to be printed. Note that '\0' is not the same as '0' or 'O' (zero or oh)

In your view loop, just add this inside your loop:

if(site[i].name)  //in pseudo code
   print the name, the place, the east, and the west

so deleted records will not be viewed - but leave it OUT of any printing to the file, because you WANT those deleted records, to remain in the file. You may write out all zeroes for east and west values if you want to - don't know why you'd need to, but you can. You can also write out a '\0' value into the first char of the place field. Again, don't know why, but you can. Your program just needs a certain placeholder, if the number of records is to be correct as you loop through the array.

Adak 419 Nearly a Posting Virtuoso

Makes sense it might do this, doesn't it?

First, it makes room for f[], then it makes room for g[]. Nothing in between is made, so it's quite probable that f[] is just beneath or above g[].

When you "walk" off the end of f[]'s boundary, what might you very well run into, except g[]?

Wouldn't be anything to rely on since it's totally undefined, but you can see how it might happen, just like that.

Now go program the right way. ;)

Adak 419 Nearly a Posting Virtuoso

Better, yes.

You're welcome.

How goes it with deletion and separation functions?

Adak 419 Nearly a Posting Virtuoso

This is your program with the tweaks I would start out with, (but it's awkward fitting it into the function descriptions you received).

I did not tweak the delete and separation functions, ran out of time.

See what you think. It's all really untested.

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <ctype.h>   //for tolower()
#define MAX 20
 
struct location
{
  char name[20],place[20];
  float east,north;
     
}; 

//Functions  -- now in alphabetical order ;)
int add_site(struct location newsite, struct location site[MAX]); //OK?
void delete_site(struct location site[MAX], int i);
int find_site(struct location newsite, struct location site[MAX]); //OK?
int menu(void); //OK?
int read_file(FILE *file); //OK?
double separation(struct location site[MAX], int i);
void view_sites(struct location site[MAX]); //OK?
 
//Main Funtion//
int main()
{	
    if(menu())
    {
      printf("\nThere was a general error in the program\n");
      return 1;
    }
   	return 0;
}
 
//Menu Function//
int menu()
{
	struct location site[MAX], newsite;
  FILE *file;  //add this
  int i, OK, numsites=0; //i is the standard iterator, and tells you nothing
  int stored;   //about the value it holds. Use var names with meaning
  char choice,q;
                 
  /*file = fopen("sites.txt" ,"rt");
  if(file==NULL) 
  {
    printf("Error opening the data file - terminating\n");
    return 1;
  }
  */  
  //Clean site array
  for(i=0;i<MAX;i++)
    site[i].name[0] = '\0'; 
  newsite.name[0]='\0';

  numsites = add_site(newsite, site); //first time, gets data from file 
                              //and returns numsites
  if(numsites==0)
  {
    printf("\nThere are no sites currently in the data file\n");
  }  
  view_sites(site);

  do 
  {
    choice='\0';
    printf("\nMenu\n%d\n",numsites);
 
    printf("[A]dd a site        [D]elete a site\n");
    printf("[F]ind a record     [S]eparation between sites\n");
    printf("[V]iew all records\n\n");
 
    printf("Your choice [or Q …
Adak 419 Nearly a Posting Virtuoso

You always want to make sure that the data file is updated before the program closes. That's true enough.

In RL, you want the data file updated regularly, if it has any changes in the array, because of the danger of losing power, someone shutting off the computer, or just a crash of the Operating system, from any cause at all.

I'll look over your program in more detail, this evening.

Oh! Ask away! The more the merrier. ;)

Adak 419 Nearly a Posting Virtuoso

OK, first thing, the corruption. For now, I advise writing out the array as text, which you ARE doing, but are you opening the file or writing to the file, using the binary mode, in some functions? I believe so, so check it. Make it all text mode, for now.

Also, (still on data corruption), you are writing out the data as:
string<space>string<space>float<space>float

Note that there is no newline on the end of the float, so ALL the data could be written out to just ONE line of text, which I'm sure you don't want. So add a newline to the fprintf() line of code, (inside the "%s ...\n" <=like so at the end).

Don't forget that you have this newline char, when you're reading the data file - add that %c right at the end of the input format string "%s %s %f %f%c" fscanf() line of code

Now for the strings themselves - you know every string in C needs an end of string char, or it's just a jumble of letters. So as you are adding data, reading data, and writing data, be consistent, and handle it as a string. Of course. ;)

I'll bet money the original file data, did not have an end of string char in place, however. The way to fix it is to put your data in, from inside your database program. It will automatically add the end of string char, for you, since you're handling …

Adak 419 Nearly a Posting Virtuoso

Your function looks very close *EXCEPT*, you are only writing out ONE record, instead of all the records (yes, even the deleted record gets written out, now that's it's marked).

Give that a shot! ;)

Adak 419 Nearly a Posting Virtuoso

Don't you have documentation that gives you the info like this?

Since your question is about a hardware problem, I would ask it, in a hardware or embedded forum. Although I'd like to help, I am not familiar with that hardware.

Adak 419 Nearly a Posting Virtuoso

I did not understand your last post. Please tell me what function you are referring to, and what the problem is.

I don't want to spend time looking through the whole program or running it, so help me to zero in on the issue here.

Adak 419 Nearly a Posting Virtuoso

I have used the end of string marker char: '\0' in the past, but AD is quite right - any char that couldn't be used in a name field, would be fine.

Once you decide what char you want to use, it's just a matter of assignment:

site[i].name[0]= '\0'; //or whatever char you want to use.

Then you have to let the program know what you're looking for, in your other functions. You don't want to be handling a "name", that has been marked with a tilde, as if it was still a valid entry.

Looking at the delete function:

void delete_site(struct location site[MAX], int i)
{

	printf("\nYou have reached the delete_site funtion\n\n");

	int j;

	FILE*file;
 
	printf("Please enter the name of the record you would like to delete:\n");

/* 
you need to enter a full name, not a single char, here. You're not looking for an empty record slot, you're looking for a record that is already entered into the database.
*/
	scanf(" %c", site[j].name);  //%s and this should be inside a for loop
/* how do you know before you look, what index (j) will have your record? */

/* you're opening files when you don't need to. 
First, work in the array, in any function -
THEN do the file work, if needed, LAST
THING.
*/



	file = fopen ("sites.txt", "r");

	for (j=0;j<MAX;j++)
		if(site[j].name == "%c")//if((strcmp(site.[j].name, target_name)==0)
		{
			printf("This site exists");
		}

/* it's a good idea to print the record on screen, 
and …
Adak 419 Nearly a Posting Virtuoso
//Add Site Function//
void add_site(struct location site[MAX], int i)
{

	printf("\n You reached the add_site function\n");
	
	FILE*file;
	int stored;

/* The file should be opened and read in, at the top of the menu() function, not down here. Otherwise you'll have to read the file in, in every function (almost).

	file = fopen("sites.txt" ,"r");
	
	while ( 1 /*!feof(file)*/ )
    {
        stored = fscanf(file,"%s %s %f %f",site[i].name,site[i].place,&site[i].east,&site[i].north);
		
        if(stored < 4)
        {
			break;
        }
    }
		
 
    fclose(file);

All the above file code should be moved to the top of menu(), outside the big loop
*/


/* You're not ready to write out data yet. Move to the bottom of this function */
	file = fopen("sites.txt" ,"a");

	if (file==NULL) { 
           printf("FAILED TO OPEN FILE!!\n\n"); 
           return 1;
        }
	
     for(i=0;i<MAX;i++) {
       if(sizeof(site[i])== '0') //nope, should be '\0' (char end of string marker)
       {
	  printf("\nPlease enter the name:\n\n");
	  scanf("%s", site[0].name);  //you want site[i], not site[0]!

	  printf("\nPlease enter the place:\n\n");
	  scanf(" %s", site[0].place);  //same, use site[1], not site[0]

/* What about East and North? They should get some value? */

         print the name and place, to ensure you've got them OK, here.
         a little check saves a lot of time, later on.
	}
	
/* You should use printf(), and save the binary writing of the records, until after 
the program is de-bugged. */
	fwrite(&site[0].name, sizeof(site), 1, file); 

/* fwrite usually writes out an entire record, all at once, not a single record field */  

// unnecessary in any case==>fwrite(&site[0].place, sizeof(site), 1, file); 

	
fclose(file);      
	                                         
}
Adak 419 Nearly a Posting Virtuoso

I don't know how archive logic works, but I would read up on the matter, and be sure I understood it (and could do a simple 2 or 3 file archive on paper), before trying to program it.

I can't solve a problem with a program, unless I really understand the problem, and know the way to solve it. The program can give you the answer, but it can't give you the right algorithm to get to the answer.

There is at least one open source compression program you can google up, but I don't know how much good it will do, without the info on the algorithm it uses.

Adak 419 Nearly a Posting Virtuoso

Get a good IDE, and understand, it will take time and a lot of work to be a decent programmer.

Learning C from the command line -- holy shit! Insane confidence killer, for a beginner. imo.

Adak 419 Nearly a Posting Virtuoso

<< ALWAYS post your code in between code tags! >>

Let's look at add_site():

/Add Site Function//
void add_site(struct location site[MAX], int i)
{

printf("\n You reached the add_site function\n");

FILE*file;

/*
You don't know if you need to open a file, at all yet. First,
see if you have an empty record in your array.
And you would never need to read in more data, from
the file, in this function. You may want to write out
data, after opening the data file using append mode.
*/

file = fopen("locations.txt" ,"r");
fclose(file);


/* not yet! */
file = fopen("locations.txt" ,"r+w");

if(strlen(site[i].name)== 0)  //should be == '\0' (zero is a number, not a char)
{

printf("Please enter the name");
scanf("%s", site[0].name);

fwrite(&site[i].name, sizeof(site), 1, file);

}

Files don't always open like we think they should. If you don't check, you
can crash your program, writing out data to a device that isn't ready to
receive anything.

if(file==NULL)
{ print a file opening error
  and any further directions
  and stop processing data (return with 1, 
  indicating an error, is normal).
}

You need a consistent plan for working with the file. I suggest opening it to read in the initial data, and then closing it, right afterward. Later on, you'll need to open it, perhaps, in append mode, to add some data to the end of the file.

Then, I suggest you close the file, immediately again. Data can be lost easily if you get …

Adak 419 Nearly a Posting Virtuoso

From the help file of Turbo C:

malloc Allocates memory.

Syntax:
void *malloc(size_t size);

Prototype in:
alloc.h stdlib.h

Remarks:
malloc allocates a block of size bytes from
the memory heap. It allows a program to
allocate memory explicitly as it's needed, and
in the exact amounts needed.

The heap is used for dynamic allocation of
variable-sized blocks of memory. Many data
structures, such as trees and lists, naturally
employ heap memory allocation.

<DOS data deleted>

Return Value:
On success, malloc returns a pointer to the
newly allocated block of memory.

If not enough space exists for the new block,
it returns null. The contents of the block are
left unchanged.

If the argument size == 0, malloc returns
null.

Portability:
malloc is available on UNIX systems and is
defined in ANSI C.

See Also:
realloc
calloc free

Example:

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

 int main(void)
 {
    char *str;

    /* allocate memory for string */
    if ((str = malloc(10)) == NULL)
    {
       printf("Not enough memory to allocate buffer\n");
       exit(1);  /* terminate program if out of memory */
    }

    /* copy "Hello" into string */
    strcpy(str, "Hello");

    /* display string */
    printf("String is %s\n", str);

    /* free memory */
    free(str);

    return 0;
 }

I'm not sure that using malloc() will make your program "less intense". It will use less stack …

Adak 419 Nearly a Posting Virtuoso

In your called functions, just add a little line of code that will show you that the program did go there:

printf("\n You reached the add_site function\n");

and don't clear your screen. This is just for debugging, of course, but something like the above, in every function you are concerned with, will help.

Looks like you have some upper case choices, and some lower case choices in your menu. You know C is case sensitive, so I'd change everything to one kind of case, and change all answers to that case, with toupper() or tolower() (part of string.h, IIRC).

Still hexed? Post up your latest code, and I'll study it some more.

Adak 419 Nearly a Posting Virtuoso

You could include <stdlib.h> and then malloc the memory for buff[]. When you no longer needed it, you could then free(buff).

That would save a lot of the static memory space, which is much more scarce than heap memory, (where malloc() gets it's memory for you).

Adak 419 Nearly a Posting Virtuoso

Although this is a very simple "flat file" database, you have to have all the basics of struct (record) and array handling, in order, to make it come together. There are a lot of parts to it, and trust me, you'll learn a LOT by working on this exercise.

else if(choice == 'a') add_site(struct location site[], int i);

this line includes the word "struct", "location", and "int", which shouldn't be included in the call to add_site().

else if(choice == 'a') add_site(site, i);

Where you use those terms like "struct", "location" and "int", is on the parameter list for the add_site() function itself:

void add_site(struct location site[MAX], int i) {
  //function code in here
}
Adak 419 Nearly a Posting Virtuoso

Don't declare a new array in add(). You should use an empty position in the array of records, you already have. Pass the array into the add function, as a parameter.

You need to close the data file, then reopen it, in "r+w" mode, rather than read mode only. This will erase the current data in the file, which you want.

Now you're ready to write all the data into it, which of course, includes the new record. There are better schemes for this, but this will do nicely for a very small database.

That's why you have no data going into the file yet - you opened it in read mode.

Adak 419 Nearly a Posting Virtuoso
fscanf(file,"%s %s %f %f",&site[i].name[0],&site[i].place[0],&site[i].east,&site[i].north);

name and place are strings (the names of which serve as a constant pointer of the right type to the array, so remove the & from the above, for those variables. Also, remove the [0], from them, as well.

Keep the & (ampersand), for the east and north members.

feof() doesn't work as you'd like it to - frequently causing a repeat of the last data in the data file, to be entered into the array.

To avoid that, remove feof() and use the return value of fscanf(). It returns the number of objects it has stored.

stored = fscanf(file, ... etc.);
if(stored < 4)
  break;  //out of the read data loop

After scanf() in menu(), add:

getchar();  //or (void) getchar();

Which will "clean up" the newline char from the keyboard buffer (badly needed here).

Use a for loop to write out the array records to the file.

Open the data file for writing, with binary mode

#define MAX 25
for(i=0;i<MAX;i++) {  //(a define for the size of your array which you should have just below your list of include files) 

  fwrite(&array[i], sizeof(NameOfStruct), 1, file); //writes out 1 entire record to the file
                                               //pointed to by "file"

While you're learning, it might be better to use text mode, and fprintf(), and write out each struct.member, individually.

Adak 419 Nearly a Posting Virtuoso

Basically I have a database stored in a text file with information about several companies. Each record contains 4 fields:

Name, Place, East, North

I want to do basic database functions (which would be listed in a menu):

1. Add a new record (in this case a company)
2. Delete a record
3. Find a specified record

etc.

I have sent you an email with a document attached telling you exactly what I need to do.

Thanks for your patience.

All the above is a repeat of what you've already posted.

I read all that - all very standard.

My question is: "What are you stuck on?" Not "What do you have to do?"

Basically, you have main() function. Before the main function, you'll prototype your struct:

struct mystruct {
   char name[30];
   char place[30];
   float or int east
   float or int north
}

;
(size of name and place are up to you) I suggest you put the name and location or place, first and second in the struct, because that's the way the data is, in the file.

At the top part of main(), you'll declare the array of structs, a char called choice, and a few other variables.

You'll have a do{ }while(choice!=q);

and inside that do while loop, you'll print up a cheery little header, then the menu options, and get the user's input into "choice":

[A]dd a record        [D]elete a record
[E]dit a record       [S]earch …
Adak 419 Nearly a Posting Virtuoso

There we go! Thanks, Narue. I'd mentioned difftime(), but veered away from it because I didn't think it would handle years and leap years.

Heads up, Nick! ;)

Adak 419 Nearly a Posting Virtuoso

If you want to use tm, the system will handle leap years extra day, for you, IIRC.
Look at your help for the tm struct, and you'll see what you need to fill out. For my (older) struct, the tm is like this:

struct tm {
    int  tm_sec,  tm_min,  tm_hour;
    int  tm_mday, tm_mon,  tm_year; 
    int  tm_wday, tm_yday;
    int  tm_isdst;
  };

mday is "day of the month", 1-31.
wday is "day of the week" Sunday is 0
yday is "day of the year" 1-366
isdst is "is Daylight Saving Time, in your local time zone? 0 No or 1,Yes

Your answer can't be an int - (depending on your system and age, of course), make it an unsigned long int, if needed.

Adak 419 Nearly a Posting Virtuoso

These are the leap years we need to work with:

1972
1976
1980
1984
1988
1992
1996
2000
2004
2008
Adak 419 Nearly a Posting Virtuoso

You'll want to define your struct above main() (make the definition global in scope), so other functions can easily make a temp struct, for editing purposes, etc.

Can you narrow down what you're stuck on doing, more precisely?

Adak 419 Nearly a Posting Virtuoso

OK, we can go this way, also.

A couple defines (or just data), to keep in mind:
SECSinHOUR 3600
SECSinDAY 86400

Adak 419 Nearly a Posting Virtuoso

Nope, on second thought I don't think difftime() is what you want. In my (old) compiler, I'd use two structs called "tm" (included in time.h). One would get my birthday data, the second one would get filled in by C itself, for now.

Then it's a matter of a little arithmetic, subtracting one tm struct members, from the other, and a bit of arithmetic on the resulting answer, and it's done. The big advantage of using the tm struct, is that the data is nicely laid out for you, for the current date/time, with it.

Let me know if you want to work with the tm struct, and need the struct definition, etc.

Sorry to confuse you, but I haven't done this kind of a program in a very long time. Lots of rust. ;)

Adak 419 Nearly a Posting Virtuoso

OK, are you looking to use difftime() ?

Here's an example, but I'm not exactly sure how it could fit into what you're doing - but it's very possible. ;)

#include <time.h>
#include <stdio.h>
#include <dos.h>
int main(void)
{
   time_t first, second;

   first = time(NULL);  /* Gets system
                           time */
   delay(2000);         /* Waits 2 secs */
   second = time(NULL); /* Gets system time
                           again */

   printf("The difference is: %f seconds\n",difftime(second,first));
   getch();

   return 0;
}
Adak 419 Nearly a Posting Virtuoso

Work it out, step by step. First, can you get the number of years, correctly?

What about the number of months, after the last full year?

Then get the number of days, after the last full month.

You see where I'm going with this: step by step, large to small:
The number of hours past the last full day,
The number of minutes after the last full hour
and lastly, the number of seconds after the last full minute.

Where are you stuck? ;)

Adak 419 Nearly a Posting Virtuoso

I'm saying I don't see how it can be right to print out result (which is?? the final answer in seconds I think), using %ld in printf().

Result is a char, and char's have a very small maximum value.

I'm approaching this from a "get the number of days, hours, minutes and seconds, and convert that entire amount to seconds", POV.

Adak 419 Nearly a Posting Virtuoso

I don't have that strptime() function, so I suggest:

1) Use an unsigned long for the seconds' data type. Int may over-run.

2) Once you get the number of days, (or whatever units you want to work with, just do the math yourself:

seconds +=hoursPerDay * secondsPerHour, + etc.

Adak 419 Nearly a Posting Virtuoso

When you don't use code tags, your code looks like the dog's breakfast, and is generally ignored.

Always highlight your code, and click on the [CODE ] icon in the top bar of the forum editor, to make your code easily readable.

First thing I see wrong is the & operator, in front of strings that you're fscanf()'ing. Strings shouldn't have the & in front of them - the name of the string is the address you want, and the right type.

If you know how to bring in data from a file, you should be able to send the data back out to a file, as well. Any problems with that?

To remove a record, first, find the record you want to remove, then zero out: ('\0'), the first char of the name of the company. Then adjust your output (to file and to printing on the screen), so that records that have companies with no name, are not shown or output to a file. (very easy).

Adding a company is just a matter of finding a record with no name if(strlen(record[i].name)== 0)

Record names must not be allowed to contain garbage values in the first char of their name, ever. They either have a valid name, or they have a '\0' (end of string char marker), as their first char.