Age | Commit message (Collapse) | Author | Files | Lines |
|
The exercises may be completed, but that doesn't mean the work is over!
I'll need to verify the correctness of the later exercises, and will
someday comb over the messier solutions that I'm less satisfied with.
I'd like to put together a modern set of solutions, too, to illustrate
how C has improved over the years. Outside interest will determine
whether this is pursued.
|
|
|
|
Well, here it is. The final solution to the final exercise! These last
few exercise solutions are not ideal by any measure of coding
excellence, but they function.
I plan to come back to this some day, with better debugging knowledge.
Then I can correct any issues.
|
|
There wasn't much to check for, but I checked for what I could think of.
|
|
I chose to implement calloc() by calling malloc.
This exercise went well, but I found it difficult to verify the contents
of the headers and buffers within memory. Valgrind showed the correct
number of bytes allocated, and a memory dump pointed to a good
result, but research was not conclusive.
|
|
This exercise uses the standard library instead of the homegrown
dirent.h outlined in the book. This is due to misbehavior in outputting
the file or directory names. This pointed to a data mismatch between the
data model supplied by the book and the data model actually used by my
operating system (GNU/Linux).
|
|
|
|
|
|
The refactor includes implementations for fflush and fclose as well,
needed in 8-03.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
This one was tricky, but the solution was rather simple.
|
|
|
|
|
|
|
|
This exercise was deceptively simple, and ended up simpler than the
original! The *scanf series of functions is very useful, but you also
have to be careful or you'll run into segfaults.
|
|
This one wasn't too bad, either! There's a minor bug in the code, but
I'm not sure how to fix it. It *technically* meets muster, though. :P
|
|
|
|
Code style should be consistent now. All future commits will be run through
astyle or they will be amended.
|
|
The solution is technically not 100% correct, but good luck figuring out
a robust solution inside Category-0 restrictions. Unicode characters
like ¬ or ♥ show up as 64-bit hex codes and I couldn't find a way to
shorten them. Then again, UTF-8 supports characters up to 8 bytes long.
Use it with plain ASCII and it looks only minorly off.
|
|
Also of note is the length that the program reports includes the newline
character at the end. This has been clarified in a comment. The exercise
text does not specify whether to include newlines as part of the length,
so it was left alone.
Removed the contributor notice, since contributor acknowledgements are
centralized.
|
|
* Improve README tone
* Add `astylerc` for use with the astyle package
* Add AUTHORS file to acknowledge contributors
|
|
A completely rewritten solution which follows the spec given in the book
exactly; make the program work for arbitrarily long input lines while
modifying `main()` only. I've only changed the name of the macro MAXLINE
to BUFFSIZE for clarity - otherwise the code is typed up exactly as
found in the book.
It demonstrates the use of a buffer without modifying any of the helper
functions.
|
|
Two cases, one file. This exercise was a welcome departure from the
recent head-scratchers. It made me think about a solution for the
pathname issue I realized would crop up, too.
I'm roughly 75% done with the book! Maybe by the time I finish it, I'll
have a Makefile ready for the project...
|
|
This exercise is probably the most challenging "function puzzle" thus
far. Modifying getword(), using various states, and the hashtable all
create an example of how small building blocks can work together to
make something.
The implementation is very simple and nowhere near completely supporting
'#define', but that's not the point. To properly support it, you'd need
to build an entire preprocessor/parser, and that's far beyond the scope
of both the exercise and book.
|
|
We're getting close to more useful data structures! Wee!
|
|
This exercise was good practice to get back into the mindset of
programming. It's not a pretty solution, but it works. I may end
up coming back to this solution, because I feel like I've missed
something that would make this exercise simpler.
|
|
|
|
|
|
This exercise improved my understanding of identifying comments and
quotes by focusing on edge cases.
|
|
This marks the end of chapter 5. Admittedly, the solution for 5-20 is
terrible, but it does what it's supposed to do. I'm just excited to move
onto chapter 6 and start learning structures!
|
|
|
|
This exercise was a real pain in the ass. The original use of
getch() and ungetch() was inferior to a line-based approach. It
really doesn't seem like the way a parser should be built, but
it taught me a little about the order of recursion. I'm convinced
that a debugger is necessary if you want to build a good parser.
This implementation doesn't recurse in a natural way, or even
enough to stack data type prefixes. Hopefully by the time I get to
5-20 I'll have enough ideas to implement something that *does*
recurse well.
|
|
I'm preparing for build automation, so everything needs to build
|
|
|
|
|
|
|
|
|
|
|
|
|
|
This exercise was somewhat irritating until I caved and used the code in
section 5.6 like the exercise suggested. The solution is not what I
think is clean, but given that [mc]*alloc haven't been covered yet, it's
probably the best one can muster.
Once I used the code in §5.6, the program fell into place. Still, it was
a neat exercise.
|
|
|
|
This one was pretty rough. At first I wanted to include a bunch of
error-catching and "smart" stuff. When I took a second look at it and
realized `itoa` returns 0 on a string, things became a bit easier. I
may have been able to outsource a few things to a function or two, but
overall I think it worked out.
|
|
|
|
|