I can pick up books on Python or Go that teach you the language while building an entire REST API. C++ has books that teach you its features while building games. C seems to lack really good learning resources and I can't imagine why for a language so ubiquitous.
Does anyone know of any C resources where you learn by doing? It doesn't have to be some crazy project, just beyond the single file toy programs I keep seeing.
There still exist such books. C is a system programming langugage so you have to look in that direction. There is a compiler book called "Game Scripting Mastery", which was an early 200X book that holds your hand through making a working Virtual Machine of a C-like scripting language. It is written in C and has the full code for that Virtual Machine. This is definitely a "learn-by-project" book.
I think you can probably find more examples by looking in that direction. There is another trick: Browse the websites of top 20 CS universities and find all their system programming labs. You will guarantee to find many mid-size C projects.
Last but not least, here is the famous awesome-C project list. Treat yourself. Many of them are walkthrough type tutorials (e.g. write a text editor in C) and can be very fun to code.
edit: link to the book https://faculty.washington.edu/jstraub/dsa/Master_2_7a.pdf
Has several small projects, it is not a book for complete beginners though.
There is also an old book which re-implements several Unix commands, but I cannot remember it's name and google is not helping.
"Furthermore, we argue that the C standard does not allow Turing complete implementations, and that its evaluation semantics does not preserve typing. Finally, we claim that no strictly conforming programs exist. That is, there is no C program for which the standard can guarantee that it will not crash." [1]
In some sense then, C is not an actual language, so no one can give definitive information about it without being totally wrong in one or two ways. I would argue this fragmentation of both the code and the user base is part of why there is almost no secondary documentation. Not even the specs are correct or complete.
[1] https://www.semanticscholar.org/paper/Subtleties-of-the-ANSI...
https://duckduckgo.com/?q=21st+century+c&t=fpas&ia=web
Helps you set up your local tooling, and covers the use of C the "modern" language.
I highly recommend checking out Udemy for a C course because their courses are typically project oriented. I believe Udemy gives a major discount for new users.
If you're just looking to better understand memory or pointers or something similar, K&R + What Every Programmer Should Know About Memory are all you really need. Throw in a book on linkers and loaders, even an old one, and you'll have more than enough info to understand what most programs are doing under the hood.
I learned the language in school and at the first few jobs I had, all embedded or systems work. If I had to learn it today, I would do the following:
1. Read K&R book on C - https://en.wikipedia.org/wiki/The_C_Programming_Language - your goal here is to just learn the syntax. Build some simple programs with what you learned, like replicate echo or cat commands.
2. I like Learn The Hardway series of books for the tools he teaches. It's really hard to be effective with C without knowing how to use a debugger or some static code analyses tools. https://learncodethehardway.org/c/ You can learn make, GDB, valgrind, etc. on your own too - plenty of O'Reilly books on the topics. I do recommend learning at least make, GDB and valgrind - they will help you build your code and figure out where you screwed up with your pointer arithmetic - which you will do.
3. Decide on what kind of projects you want to work with C. I learned by rebuilding some of the standard Unix utilities (e.g. curl or wget) as well as some systems programs, like a network scanner.
4. Build something a lot more complex, like a bootloader for an Arduino board. As in, get a cheap Arduino nano and write your own little bootloader that will load a simple program that blinks an LED. Plenty of other alternatives, e.g. build a basic git implementation. Try your hand at building a JSON parser - you'll hate strings by the end though.
5a. Get a book on Linux device drivers and go through it; build a few of the drivers - it's really not that hard. The Linux kernel is just another framework. You can also just look at https://kernelnewbies.org/ to see what else you can do and find other resources.
5b. Alternatively, build your own database. Can be a clone of Dynamo or Redis or some kind of RDBMS. You can even build your own pub/sub system if you want. Whatever you're curious about.
6. If you really like working with C, go through a Data Structures course and implement all of that stuff in C. You'll hate yourself but you'll learn a lot about the language. By now, you'll have picked up a bunch of that stuff anyways, but don't let not knowing quicksort algo stop you from building something. All the sorting/searching algos are better learned once you're comfortable debugging your code and looking for pointer issues.
Personally, I love working with C. It can be incredibly frustrating, but it's the first language I learned, so it's my home. In the last 10 years, I only worked with it when doing embedded work. I'll reach for Go as a system's programming language first (haven't learned Rust yet). For web development, there are too many modern frameworks and languages that are much much better than C.