[toc]
Learning C by using the book Head First C, by David Griffiths and Dawn Griffiths
- Prints "The deck is hot. Increase bet." to the console.
- Prints "I must not write code in class" 10 times.
- Gets a boyfriend name and prints the message: "Dear $name.\n\n You are history."
- Prints "Hearts"
/*
* Program to evaluate face values.
* Released under the Vegas Public License.
* (c)2014 The College Blackjack Team.
*/
#include <stdio.h>
#include <stdlib.h>
int main()
{
char card_name[3];
puts("Enter the card_name: ");
scanf("%2s", card_name);
int val = 0;
if (card_name[0] == 'K') {
val = 10;
} else if (card_name[0] == 'Q') {
val = 10;
} else if (card_name[0] == 'J') {
val = 10;
} else if (card_name[0] == 'A')
{
val = 11;
} else {
val = atoi(card_name);
}
printf("The card value is %i\n", val);
return 0;
}
A. Won't compile B. Will run as intended C. Won't compile D. Won't compile
Code | Output |
---|---|
y = x - y; |
00 11 21 32 42 |
y = y + x; |
00 11 23 36 410 |
y = y + 2; \n if (i > 4)\n y = y - 1; |
02 14 25 36 47 |
x = x + 1; \n y = y + x |
11 34 59 |
if (y < 5) {x = x + 1; if (y < 3) {x = x - 1;}} |
02 14 36 48 |
- We’ll start with 30 bottles - that’s about 180 glasses
- While there’s still some fizz:
- Display the current stock
- Enter the number of glasses ordered
- Adjust the stock
- Then just go round again
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int stock = 180;
char order_string[3];
int order;
while (stock > 0)
{
printf("The current stock is: %i\n", stock);
scanf("%2s", order_string);
order = atoi(order_string);
stock = stock - order;
printf("You ordered %i glasses\n", order);
}
puts("We are out of stock, baby!\n");
return 0;
}
- strchr: Find the location of a character inside a string
- strcmp: Compare two strings together
- strstr: Find the location of a string inside another string
- strcpy: Find the length of a string
- strcat: Concatenate two strings together
Wich of the functions above should you use for the jukebox program? strstr
- The string can't be updated
- We're swapping characters outside the string
- The string isn't in memory
- Something else
void print_reverse(char* s)
{
size_t len = strlen(s);
char* t = s + len -1;
while (t >= s)
{
printf("%c", *t);
t = t - 1;
}
puts(" ");
}
- mulberry
- yrrebwarts
- sharonfruit
- tiurfiwik
- blueberry
- yrrebkcalb
- starfruit
- tiurfilgu
In this chapter we will build a program that parses data from CSV to JSON
#include <stdio.h>
int main(void)
{
float latitude;
float longitude;
char info[80];
while (scanf("%f,%f,%79[^\n]", &latitude, &longitude, info) == 3)
{
if ((latitude > 26) && (latitude < 34))
{
if ((longitude > -76) && (longitude < -64))
{
printf("%f,%f,%s", latitude, longitude, info);
}
}
}
return 0;
}
Message 1: The submarine will surface at 9PM Message 2: Buy six eggs and some milk
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<title>Head First C Map</title>
<style>
html, body {
height: 100%;
margin: 0;
padding: 0;
}
#map {
height: 100%;
}
</style>
</head>
<body>
<script src="output.json" type="text/javascript">
</script>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false">
</script>
<div style="overflow:hidden;height:100%;width:100%;">
<div id="gmap_canvas" style="height:100%;width:100%;"></div>
<style>#gmap_canvas img{max-width:none!important;background:none!important}</style>
</div>
<script type="text/javascript">
function init_map(){
var c_lat = 0;
var c_lon = 0;
for (var i = 0; i < data.length; i++) {
c_lat += data[i].latitude;
c_lon += data[i].longitude;
}
if (data.length > 0) {
c_lat /= data.length;
c_lon /= data.length;
}
var myOptions = {zoom:14,center:new google.maps.LatLng(c_lat,c_lon),mapTypeId: google.maps.MapTypeId.ROADMAP};
map = new google.maps.Map(document.getElementById("gmap_canvas"), myOptions);
for (var i = 0; i < data.length; i++) {
(function fred(data, i) {
var lat = data[i].latitude;
if ((lat < -90) || (lat > 90)) {
alert("Invalid latitude: '" + lat + "'");
return;
}
var lng = data[i].longitude;
if ((lng < -90) || (lng > 90)) {
alert("Invalid longitude: '" + lng + "'");
return;
}
var marker = new google.maps.Marker({map: map,position: new google.maps.LatLng(lat, lng)});
var infowindow = new google.maps.InfoWindow({content:data[i].info });
google.maps.event.addListener(marker, "click", function(){
infowindow.open(map,marker);});
})(data, i);
}
}
google.maps.event.addDomListener(window, 'load', init_map);
</script>
</body>
</html>
float mercury_day_in_earth_days();
int hours_in_an_earth_day();
int main()
{
float length_of_day = mercury_day_in_earth_days();
int hours = hours_in_an_earth_day();
float day = length_of_day * hours;
- You can compile the code
- You should display a warning
- The program will work
float mercury_day_in_earth_days();
int main()
{
float length_of_day = mercury_day_in_earth_days();
int hours = hours_in_an_earth_day();
float day = length_of_day * hours;
- You can compile the code
- You should display a warning
- The program will work
int main()
{
float length_of_day = mercury_day_in_earth_days();
int hours = hours_in_an_earth_day();
float day = length_of_day * hours;
- You can compile the code
- You should display a warning
- The program will work
float mercury_day_in_earth_days();
int hours_in_an_earth_day();
int main()
{
int length_of_day = mercury_day_in_earth_days();
int hours = hours_in_an_earth_day();
float day = length_of_day * hours;
- You can compile the code
- You should display a warning
- The program will work
- thruster.c
- turbo.c
- graticule.c
- servo.c
- thruster.o
- turbo.o
- graticule.o
- servo.o
- ems
- microwave.c
- popcorn.c
- juicer.c
- microwave.o
- popcorn.o
- juicer.o
- galley
oggswing: oggswing.c oggswing.h
[TAB] gcc oggswing.c -o oggswing
swing.ogg: whitennerdy.ogg oggswing
[TAB] oggswing whitennerdy.ogg swing.ogg
void catalog(struct fish f)
{
printf("%s is a %s with %i teeth. He is %i\n",
f.name, f.species, f.teeth, f.age
);
return;
}
int main(void)
{
struct fish snappy = {"Snappy", "Piranha", 69, 4};
catalog(snappy);
return 0;
}
struct exercise
{
const char* description;
float duration;
};
struct meal
{
const char* ingredients;
float weight;
};
struct preferences
{
struct meal food;
struct exercise exercise;
};
struct fish
{
const char* name;
const char* species;
int teeth;
int age;
struct preferences care;
}
- How would you write this data in C?
struct fish snappy = {"Snappy", "Piranha", 69, 4, {{"meat", 0.2}, {"swim in the jacuzzi", 7.5}}};
- Complete the label function so it produces output like this:
Name:Snappy
Species:Piranha
4 years old, 69 teeth
Feed with 0.20 lbs of meat and allow to swim in the jacuzzi for 7.50 hours
void label(struct fish a)
{
printf("Name: %s\nSpecies: %s\n%i years old, %i teeth\n",
a.name, a.species, a.teeth, a.age
);
printf("Feed with %2.2f libs of %s and allow to %s for %2.2f hours\n",
a.care.food.weight, a.care.food.ingredients,
a.care.exercise.description, a.care.exercise.duration
);
}
#include <stdio.h>
typedef struct
{
float tank_capacity;
int tank_psi;
const char* suit_material;
} equipment;
typedef struct scuba
{
const char* name;
equipment kit;
} diver;
void badge(diver d)
{
printf("Name: %s Tank: %2.2f(%i) Suit: %s\n",
d.name, d.kit.tank_capacity, d.kit.tank_psi, d.kit.suit_material);
return;
}
int main(void)
{
diver randy = {"Randy", {5.5, 3500, "Neoprene"}};
badge(randy);
return 0;
}
c margarita m = {2.0, 1.0, {2}}
c margarita m = {2.0, 1.0, {0.5}}
c margarita m = {2.0, 1.0, {.lime_pieces=1}}
margarita m = {2.0, 1.0, {0.5}};
[x] Compiles [ ] Does not compile
margarita m;
m = {2.0, 1.0, {0.5}};
[ ] Compiles [x] Does not compile Explanation: if the declaration and the assignment are in different lines, the compiler thinks you are creating an array
typedef struct
{
unsigned int first_visit: 1;
unsigned int come_again: 1;
unsigned int fingers_lost: 4;
unsigned int shark_attack: 1;
unsigned int day_a_week: 3;
}
-
Before:
Amity -> Craggy -> Isla Nublar -> Shutter Skull -
After: Amity -> Craggy -> Skull -> Isla Nublar -> Shutter
- How many pieces of data were left in the heap? 1
- What was the piece of data left in the heap? A question (char*)
- Which line (or lines) of code caused the leak?
current->question = strdup(question);
The pointer is set to a new location without releasing the old one 4. How do you plug the leak?
free(current->question);
current->question = strdup(question);
Solving the problem speller, the Problem Set 5 of Harvard CS50x 2020. For this problem, given 1) a text file with all english words and 2) a text file the program should write a file with all the misspellings in the text, considering a misspelling as a word or expression that is not in the input 1.
To solve this problem in C, I used a Trie to store the words from the dictionary, since it's Big O notation is O(1) for this case;
Each node of the trie represent a character. In each trie, an unsigned int represents if the word exists or not
At the end of the search, the trie is released with a recursive function
void find()
{
int i;
puts("Search results");
puts("--------------------");
for (i = 0; i < NUM_ADS; i++)
{
if (strstr(ADS[i], "sports") && !strstr(ADS[i], "bieber"))
{
printf("%s\n", ADS[i]);
}
}
puts("--------------------");
return;
}
- Find someone who likes sports but not bieber
- Find someone who likes sports or workout
- Find a non-smoker who likes theater
- Find someone who likes theater arts or dining
unsigned int sports_no_bieber(char* s)
{
return (strstr(s, "sports") && !strstr(s, "bieber"));
}
unsigned int sports_or_workout(char* s)
{
return (strstr(s, "sports") || strstr(s, "working out"));
}
unsigned int ns_theater(char* s)
{
return (strstr(s, "NS") && strstr(s, "theater"));
}
unsigned int arts_theater_or_dining(char* s)
{
return (strstr(s, "arts") || strstr(s, "theater") || strstr(s, "dining"));
}
- Sort integer scores, with the smallest value
int compare_scores(const void* score_a, const void* score_b)
{
int a = *(int *)score_a;
int b = *(int *)score_b;
return a-b;
}
- Sort integer scores, with the largest first
int compare_scores(const void* score_a, const void* score_b)
{
int a = *(int *)score_a;
int b = *(int *)score_b;
return b-a;
}
- Sort the rectangles in area order, smallest first
typedef struct
{
int width;
int height;
} rectangle;
int compare_areas(const void* a, const void* b)
{
rectangle* rect_a = (rectangle *)a;
rectangle* rect_b = (rectangle *)b;
return ((rect_a->height) * (rect_a->width)) - ((rect_b->height) * (rect_b->width));
}
- Sort a list of names in alphabetical order, case sensitive
int compare_names(const *void a, const *void)
{
char** str_a = (char **)a;
char** str_b = (char **)b;
return strcmp((*str_a), (*str_b));
}
- Sort the rectangles in area order, largest first
int compare_areas_desc(const *void a, const *void b)
{
return -compare_areas(a, b);
}
- Sort a the names in reverse alphabetical order
int compare_names_desc(const *void a, const *void b)
{
return -compare_names(a, b);
}
Write a variadic function that calculates the total price of drinks for the Head First Lounge
double price(int count, ...)
{
va_list drinks;
va_start(drinks, count);
int i;
double total = 0;
for (i = 0; i < count; i++)
{
total += cost(va_arg(drinks, enum drink));
}
va_end(drinks);
return total;
}
- Start by creating an object file called hfcal.o; The hfcal.o header is going to be stored in ./includes:
hfcal.o: hfcal.h hfcal.c
gcc -c hfcal.c -I./includes -o hfcal.o
- Next, they need to create a program called elliptical.o from the elliptical.c test program
elliptical.o: elliptical.c
gcc -I./includes -c elliptical.c -o elliptical.o
- Now, you need to create an archive library from hfcal.o and store it in ./libs
./libs/libhfcal.a: hfcal.o
ar -rcs ./libs/libhfcal.a hfcal.o
- Finally, create the elliptical executable from elliptical.o and the hfcal archive
elliptical: elliptical.o ./libs/libhfcal.a
gcc elliptical.o -I./includes -L./libs -lhfcal -o elliptical
- Assuming that you are already in the same directory as the hfcal_UK.c file and that you have write permissions on all the directories, what commands would you need to type to compile this new version of the library?
gcc -fPIC -c hfcal_UK.c -o hfcal_UK.o
gcc -shared hfcal_UK.o -o /usr/local/lib/libhfcal.so
- If the treadmill’s main application is called /opt/apps/treadmill, what would you need to type in to run the program?
/opts/apps/treadmill
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
char* now()
{
time_t t;
time (&t);
return asctime(localtime(&t));
}
/* Master control program utility */
/* Records guard patrol check-ins */
int main(void)
{
char comment[80];
char cmd[80];
fgets(comment, 80, stdin);
sprintf(cmd, "echo '%s %s' >> reports.log", comment, now());
system(cmd);
return 0;
}
Uses | Character |
---|---|
List of args | l |
Array/vector of args | v |
Search in PATH | p |
Use environment variables | e |
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
int main(void)
{
if (execl("/sbin/ifconfig", "/sbin/ifconfig", NULL) == -1)
{
if (execlp("ipconfig", "ipconfig", NULL) == -1)
{
fprintf(stderr, "Cannot run ifconfig: %s", strerror(errno));
return 1;
}
}
return 0;
}
Code for the program "coffe":
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char *w = getenv("EXTRA");
if (!w)
w = getenv("FOOD");
if (!w)
w = argv[argc - 1];
char *c = getenv("EXTRA");
if (!c)
c = argv[argc - 1];
printf("%s with %s\n", c, w);
return 0;
}
Test program:
#include <string.h>
#include <stdio.h>
#include <errno.h>
int main(int argc, char *argv[]){
/* ---------- CODE GOES HERE ------------ */
fprintf(stderr, "Can't create order: %s\n", strerror(errno));
return 1;
}
return 0;
}
In this chapter I've learned how to open other applications using C;
# Copyright (C) 2011 by D+D Griffiths
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
import requests
import os
import re
import sys
import string
import unicodedata
import getopt
import xmltodict
import pprint
def usage():
print("Usage:\npython rssgossip.py [-uh] <search-regexp>")
try:
opts, args = getopt.getopt(sys.argv[1:], "uh", ["urls", "help"])
except getopt.GetoptError as err:
print(str(err))
usage()
sys.exit(2)
include_urls = False
for o, a in opts:
if o == "-u":
include_urls = True
elif o in ("-h", "--help"):
usage()
sys.exit()
else:
assert False, "unhandled option"
searcher = re.compile(args[0], re.IGNORECASE)
site_re = re.compile(r"http(s)?://rss(feeds)?.(.*).com")
for url in os.environ['RSS_FEED'].split():
feed = requests.get(url).content
dom = xmltodict.parse(feed)
fmt_url = site_re.search(url)
print(f"\n\n______________ Searching on {fmt_url.group(3).capitalize()} __________________\n\n\n")
forecasts = []
for desc in dom['rss']['channel']['item']:
if match := searcher.search(desc['title']):
print(f" ==== {desc['title'].upper()} ===\n")
print(desc['description'])
if (include_urls):
print(f"\t{desc['link']}")
print("\n\n")
print("__________________________________________________________________\n")
sys.exit(0)
int main(int argc, char* argv[])
{
char* phrase =
}
close(fd[0]);
dup2(fd[1], 1);
# | Data Stream |
---|---|
0 | Standard Input |
1 | |
2 | Standard Error |
3 | |
4 | Write end to the pipe |
dup2(fd[0], 0);
close(fd[1]);
# | Data Stream |
---|---|
0 | |
1 | Standard output |
2 | Standard Error |
3 | Read end of the pipe |
4 |
int main(void)
{
catch_signal(SIGINT, handle_shutdown);
listener_d = open_listener_socket();
/* ___________ Bind _____________ */
bind_to_port(listener_d, 30000);
/* ___________ Listen _____________ */
listener_socket(listener_d, 10);
struct sockaddr_storage client_addr;
unsigned int address_size = sizeof(client_addr);
char buff[255];
while (1)
{
/* ___________ Accept ___________ */
int connect_d = accept(listener_d, (struct sockaddr *)&client_addr, &address_size);
if (connect_d == -1)
{
error("Can't open secondary socket!");
}
if (!fork())
{
close(listener_d);
/* __________ Begin ___________ */
say(connect_d, "Knock! Knock!\r\n");
int status = read_in(connect_d, buff, sizeof(buff));
if (status == -1)
{
fprintf(stderr, "Could not listen to response");
close(connect_d);
}
if (strncasecmp(buff, "Who's there?", 12) != 0)
{
say(connect_d, "The Internet Knock Knock Protocol requires you to say 'Who's there?'.\nConnection reset\n");
close(connect_d);
}
say(connect_d, "Oscar\r\n");
int status2 = read_in(connect_d, buff, sizeof(buff));
if (status2 == -1)
{
fprintf(stderr, "Could not listen to response");
close(connect_d);
}
if (strncasecmp(buff, "Oscar who?", 10) != 0)
{
say(connect_d, "The Internet Knock Knock Protocol requires you to say 'Oscar who?'. \nConnection reset\n");
close(connect_d);
}
say(connect_d, "Oscar silly question, you get a silly answer.\r\n");
close(connect_d);
exit(0);
}
close(connect_d);
}
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
int beers = 2000000;
void* drink_lots(void* a)
{
int i;
for (i = 0; i < 100000; i++)
{
beers--;
}
return NULL;
}
int main(void)
{
pthread_t threads[20];
int t;
printf("%i bottles of beer.\n", beers);
for (t = 0; t < 20; t++)
{
pthread_create(threads[t], NULL, drink_lots, NULL);
}
void* result;
for (t = 0; t < 20; t++)
{
pthread_join(threads[t], &result);
}
printf("There are now %i beers.\n", beers);
return 0;
}
The variable is not reduced to zero because multiple threads try to update it at the same time and end up writing the wrong value;