Reading a file to linked lists?!

This is a discussion on Reading a file to linked lists?! within the C Programming forums, part of the General Programming Boards category; Hi. I have to write a program that reads from a text file, which contains a list of stock hourly ...

Each company data will be kept in a structure that contains: a pointer for the name, an array of the prices, and the average price for the day. The structures will be kept in a linked list. Each node structure will contain a pointer to one company data, and a pointer to the next node structure.

1. read whole line into the temp buffer with fgets
2. Allocate new COMPANYDATA
3. parse stock data into hourlyPrices array (for example with strtod calls)
4. Find a start of the company name and allocate buffer to store it
5. Copy Company name to allocated buffer, set the pointer inside COMPANYDATA as well as avg price
6. if the above is successful - create new node, set the pCompanyData pointer and insert this node in the list according to company name sorting order.
7. do the above in the loop till all the file is read.

Each company data will be kept in a structure that contains: a pointer for the name, an array of the prices, and the average price for the day. The structures will be kept in a linked list. Each node structure will contain a pointer to one company data, and a pointer to the next node structure.

The node structure sounds atypical. Usually you'll see the companies defined as a linked list:

Just for fun, I wrote some code using setlocale() to use the user's preferred locale (language rules) for sorting the names using strcoll(), and getline() provided by POSIX.1-2008 -compatible C libraries to read lines of any length.

which allows any number of prices per company. The program itself takes one or more input file names as command-line parameters, reads them all into a single linked list sorted by name (calculating the average at the same time for each company), and prints out the summary. Using

I ended up having about 190 lines of code, not counting comments or empty lines, so it's definitely not that complicated to do.

I was a bit lazy, and instead of sorting the list (using one of the efficient sorting algorithms for linked lists), I simply build the list by adding each new entry to the correct location by traversing the list from the start for each insertion.
I do have a reason, though. Inserting the items into a (balanced) tree is much more efficient wall-clock-wise for this case, than sorting the list afterwards. And transforming the list into a tree requires very small changes to the structure.

You see, in most cases, reading data from disk is the bottleneck, and doing the "insertion" work instead of waiting for disk reads to complete, is free. If you do the sort afterwards, even if the sort was lightning fast, it's still additional wall clock time taken. This applies always when disk reads are slower than insertion. Rather surprising, isn't it?

Originally Posted by orangePeel

My question is, how do I read the data from the file one line at a time, and insert them alphabetically one by one?

Use fgets() to read each line into a buffer. (I used getline() instead, because it dynamically allocates and resizes the buffer; but only POSIX.1-2008 -compatible C libraries provide it. Microsoft does not, AFAIK; just about every other recent C library does.)

To sort strings properly, you should use locales. Include <locale.h>, and call setlocale(LC_COLLATE, ""); at the start of your program, and you're done. That makes strcoll() compare the two strings using rules from user's current locale. These are standard C89/C99 functions, and should work even in Windows.

To have the list sorted according to the names, you have two options:

Insert new companies into the correct position
You can do this simply by comparing the new name and each name in the existing list in turn, advancing in the list, until the new name comes before the name in the list; you insert the new company there.
This is very simple to implement -- all you really need to worry about is the first company (when the list is empty, or the new company is inserted in front of the existing list) --, but it is not efficient if you have a lot of data.

Insert new company at the beginning of the list, and sort afterwards
Prepending to a singly-linked list is trivial, literally just two statements.
Sorting linked lists is an interesting question, since there are a lot of algorithms, and many algorithms that are good for sorting arrays are not that good for sorting linked lists, and vice versa. (You can work around that by using an array of pointers, and sorting the array using e.g. quicksort.)

If the exercise is about sorting, do the latter, otherwise do the former.
For real applications, use a tree instead, for better performance.

Ooops. Didn't notice that....It's ok, though. I pretty much started all over again and now everything seems to work ok. However, my teacher wants me to use a counter to count the number of companies as I read them. How can I do that? I tried doing: