commit 860c025165ef75889e02c3386dd48f8e7aec5895 Author: Jack-Benny Persson Date: Fri Oct 1 20:24:05 2021 +0200 Initial commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..c5d2809 --- /dev/null +++ b/README.md @@ -0,0 +1,38 @@ +# C-programmering i Linux, macOS, BSD och Solaris (tredje utgåvan) +Här finns du all exempelkod för tredje utgåvan av boken *C-programmering i +Linux, macOS, BSD och Solaris* (ISBN: 978-91-983300-7-6). + +Boken går att köpa från [CyberInfo Sverige](https://www.cyberinfo.se/bocker/), +[Bokus](https://www.bokus.com/cgi-bin/product_search.cgi?publisher=CyberInfo%20Sverige) +och +[Adlibris](https://www.adlibris.com/se/sok?filter=publisher%3ACyberInfo%20Sverige) +från och med hösten/vintern 2021. + +Är du nyfiken på boken så titta gärna i [innehållsförteckningen](https://www.cyberinfo.se/dokument/c-prog_innehallsforteckning_3e_utg.html). + +## Baksidetexten +**C-programmering i Linux, macOS, BSD och Solaris** lär först ut grunderna i +C-programmering så att vi har en stabil grund att stå på. Denna del vänder sig +mot de som är nya på C-programmering eller för de som behöver fräscha upp sina +C-kunskaper. Därefter börjar vi att programmera alltmer mot Unixsystem med +hjälp av bland annat systemanrop. Vi lär oss att skapa och använda demoner, +standard input- och output, filrättigheter, FIFO, processhantering, make-filer, +meddelandeköer med mera. Vi får också lära oss hur man kopplar samman flera +program med hjälp av rörledningar och skalskript. Mot slutet av boken tittar vi +på hur man använder felsökningsverktyg som GDB, LLDB och Valgrind. + +Grundtanken med boken är att du som läsare bara ska behöva en enda bok för att +komma igång att utveckla program och verktyg för Unixsystem. Boken är uppbyggd +på devisen att lära genom exempel. I boken finns över 180 exempelprogram, både +stora och små. Efter varje kapitel finns dessutom övningsuppgifter, så att du +som läsare ska kunna arbeta med boken på egen hand. + +I denna tredje utgåva har stora delar skrivits om för att göra boken mer +lättläst, relevant och uppdaterad. Bland annat har kapitlet om IPC utökats till +att även innefatta Unix-sockets. Ett helt kapitel om TCP/IP-programmering har +också lagts till. En del förbättringar har också gjorts av exempelprogrammen i +boken. + +## Framsida +![C-programmering i Linux, macOS, BSD och +Solaris](c-prog-tredje-utg-framsida.png) diff --git a/c-prog-tredje-utg-framsida.png b/c-prog-tredje-utg-framsida.png new file mode 100755 index 0000000..d033582 Binary files /dev/null and b/c-prog-tredje-utg-framsida.png differ diff --git a/kapitel10/loopa-pekaradresser.c b/kapitel10/loopa-pekaradresser.c new file mode 100644 index 0000000..514623b --- /dev/null +++ b/kapitel10/loopa-pekaradresser.c @@ -0,0 +1,16 @@ +#include +#define SIZE 11 + +int main(void) +{ + int i; + char namn[SIZE] = "Jack-Benny"; + printf("Adressen till 'namn': %p\n", (void*)&namn); + + for (i=0; i %p\n", i, (void*)&namn[i]); + } + + return 0; +} diff --git a/kapitel10/pekararitmetik-ex1.c b/kapitel10/pekararitmetik-ex1.c new file mode 100644 index 0000000..39f6970 --- /dev/null +++ b/kapitel10/pekararitmetik-ex1.c @@ -0,0 +1,18 @@ +#include +#define LANGD 5 + +int main(void) +{ + int i; + int x[LANGD] = {0, 1, 2, 3, 4}; + int *px; + + px = x; + + for (i = 0; i + +int main(void) +{ + int i; + char fnamn[] = "Jack-Benny"; + char *enamn = "Persson"; + + printf("Förnamn: %s\n", fnamn); + printf("Efternamn: %s\n\n", enamn); + + printf("Förnamn: %p %p\n", (void*)&fnamn, (void*)fnamn); + printf("Efternamn: %p %p\n", (void*)&enamn, (void*)enamn); + + /* Skriv ut ett tecken i taget med mellanslag mellan varje + tecken. Detta görs genom att addera 1 till pekarvariabeln + för varje iteration */ + for (i=0; i<=7; i++) + { + printf("%c ", *enamn); + enamn = enamn + 1; + } + printf("\n"); + return 0; +} diff --git a/kapitel10/pekare-ex1.c b/kapitel10/pekare-ex1.c new file mode 100644 index 0000000..89e8836 --- /dev/null +++ b/kapitel10/pekare-ex1.c @@ -0,0 +1,9 @@ +#include + +int main(void) +{ + float pi = 3.14159; + printf("Adressen till 'pi' är: %lu\n", &pi); + + return 0; +} diff --git a/kapitel10/pekare-ex2.c b/kapitel10/pekare-ex2.c new file mode 100644 index 0000000..5dfd2cf --- /dev/null +++ b/kapitel10/pekare-ex2.c @@ -0,0 +1,9 @@ +#include + +int main(void) +{ + float pi = 3.14159; + printf("Adressen till 'pi' är: %p\n", (void*)&pi); + + return 0; +} diff --git a/kapitel10/pekare-till-falt.c b/kapitel10/pekare-till-falt.c new file mode 100644 index 0000000..7a657af --- /dev/null +++ b/kapitel10/pekare-till-falt.c @@ -0,0 +1,10 @@ +#include +#define SIZE 11 + +int main(void) +{ + char namn[SIZE] = "Jack-Benny"; + printf("Adressen till 'namn': %p\n", (void*)&namn); + + return 0; +} diff --git a/kapitel10/pekare-till-pekare-ex1.c b/kapitel10/pekare-till-pekare-ex1.c new file mode 100644 index 0000000..10b0c3b --- /dev/null +++ b/kapitel10/pekare-till-pekare-ex1.c @@ -0,0 +1,15 @@ +#include + +int main(void) +{ + int x = 5; + int *px; + int **ppx; + + px = &x; + ppx = &px; + + printf("%d\n", **ppx); + + return 0; +} diff --git a/kapitel10/pekare-till-pekare-ex2.c b/kapitel10/pekare-till-pekare-ex2.c new file mode 100644 index 0000000..85fd3ad --- /dev/null +++ b/kapitel10/pekare-till-pekare-ex2.c @@ -0,0 +1,36 @@ +#include +#define LANGD 3 + +int main(void) +{ + int i; + char *ord[LANGD]; + char *pc; + char **ppc; + + ord[0] = "hund"; + ord[1] = "katt"; + ord[2] = "kanin"; + + /* Skriv ut de tre strängarna */ + for (i = 0; i < LANGD; i++) + { + printf("%s\n", ord[i]); + } + printf("\n"); + + /* Skriv ut tecken för tecken */ + for (i = 0; i < LANGD; i++) + { + ppc = ord + i; + pc = *ppc; + while (*pc != '\0') + { + printf("%c ", *pc); + pc = pc + 1; + } + printf("\n"); + } + + return 0; +} diff --git a/kapitel10/pekarvar-ex1.c b/kapitel10/pekarvar-ex1.c new file mode 100644 index 0000000..bf64bbf --- /dev/null +++ b/kapitel10/pekarvar-ex1.c @@ -0,0 +1,22 @@ +#include + +int main(void) +{ + /* Skapa vanliga variabler & fält */ + float pi = 3.14159; + + /* Deklarera pekarna */ + float *ppi; + + /* Sätt pekaren till adressen av variabeln */ + ppi = π + + /* Skriv ut det som pekaren pekar på och dess innehåll */ + printf("Adressen till 'pi': %p\n", (void*)&pi); + printf("'pi' innehåller: %.5f\n\n", pi); + printf("Adressen till 'ppi': %p\n", (void*)&ppi); + printf("'ppi' pekar på värdet: %.5f\n", *ppi); + printf("'ppi' innehåller: %p\n", (void*)ppi); + + return 0; +} diff --git a/kapitel10/pekarvar-ex2.c b/kapitel10/pekarvar-ex2.c new file mode 100644 index 0000000..bb693d5 --- /dev/null +++ b/kapitel10/pekarvar-ex2.c @@ -0,0 +1,15 @@ +#include + +int main(void) +{ + char fnamn[] = "Jack-Benny"; + char *enamn = "Persson"; + + printf("Förnamn: %s\n", fnamn); + printf("Efternamn: %s\n\n", enamn); + + printf("Förnamn: %p %p\n", (void*)&fnamn, (void*)fnamn); + printf("Efternamn: %p %p\n", (void*)&enamn, (void*)enamn); + + return 0; +} diff --git a/kapitel10/pekarvar.c b/kapitel10/pekarvar.c new file mode 100644 index 0000000..667c778 --- /dev/null +++ b/kapitel10/pekarvar.c @@ -0,0 +1,23 @@ +#include +#define SIZE 11 + +int main(void) +{ + /* Skapa vanliga variabler & fält */ + float pi = 3.14159; + char namn[SIZE] = "Jack-Benny"; + + /* Deklarera pekarna */ + float *ppi; + char *pnamn; + + /* Sätt pekarna till adressen av variablerna */ + ppi = π + pnamn = &namn[5]; + + /* Skriv ut det som pekarna pekar på */ + printf("Pi = %.5f\n", *ppi); + printf("Namn = %s\n", pnamn); + + return 0; +} diff --git a/kapitel11/call-by-ref.c b/kapitel11/call-by-ref.c new file mode 100644 index 0000000..5dd6555 --- /dev/null +++ b/kapitel11/call-by-ref.c @@ -0,0 +1,17 @@ +#include + +void inc(int *tal); + +int main(void) +{ + int x = 5; + printf("x är nu: %d\n", x); + inc(&x); + printf("x är nu: %d\n", x); + return 0; +} + +void inc(int *tal) +{ + *tal = *tal + 3; +} diff --git a/kapitel11/falt-arg-ex1.c b/kapitel11/falt-arg-ex1.c new file mode 100644 index 0000000..795dfb9 --- /dev/null +++ b/kapitel11/falt-arg-ex1.c @@ -0,0 +1,19 @@ +#include + +void say(char *namn); + +int main(void) +{ + char namn01[] = "Kalle"; + char *namn02 = "Lisa"; + + say(namn01); + say(namn02); + say("Jack-Benny"); + return 0; +} + +void say(char *namn) +{ + printf("Hej %s, hur är läget?\n", namn); +} diff --git a/kapitel11/falt-arg-ex2.c b/kapitel11/falt-arg-ex2.c new file mode 100644 index 0000000..132ef21 --- /dev/null +++ b/kapitel11/falt-arg-ex2.c @@ -0,0 +1,20 @@ +#include + +float medel(int tal[], int antal); + +int main(void) +{ + int x[] = {40, 42, 39, 37, 28}; + printf("Medelvärdet är: %.1f\n", medel(x, 5)); + return 0; +} + +float medel(int tal[], int antal) +{ + int i; + int sum = 0; + for (i = 0; i + +int main(int argc, char **argv) +{ + int i; + printf("Du har angett %d st argument\n", argc); + for (i = 0; i +#include +#include + +char *say(char namn[]); + +int main(void) +{ + char *mening = say("Jack-Benny"); + printf("%s\n", mening); + free(mening); + return 0; +} + +char *say(char namn[]) +{ + char *str; + str = calloc(50, sizeof(char)); + strncat(str, "Hej ", 4); + strncat(str, namn, 45); + return str; +} diff --git a/kapitel11/return-flt-fail.c b/kapitel11/return-flt-fail.c new file mode 100644 index 0000000..2d588bf --- /dev/null +++ b/kapitel11/return-flt-fail.c @@ -0,0 +1,18 @@ +#include +#include + +char *say(char namn[]); + +int main(void) +{ + printf("%s\n", say("Jack-Benny")); + return 0; +} + +char *say(char namn[]) +{ + char str[50] = { 0 }; + strncat(str, "Hej ", 4); + strncat(str, namn, 45); + return str; +} diff --git a/kapitel11/simple-ls-ver1.c b/kapitel11/simple-ls-ver1.c new file mode 100644 index 0000000..ae36b08 --- /dev/null +++ b/kapitel11/simple-ls-ver1.c @@ -0,0 +1,100 @@ +#define _XOPEN_SOURCE 500 +#include +#include +#include +#include + +void printUsage(char *arg); + +int main(int argc, char **argv) +{ + unsigned int typ; + char opt[4] = { 0 }; + + /* Skapa pekare och struct */ + DIR *d; + struct dirent *dir; + struct stat s; + + /* Läs in aktuell katalog */ + d = opendir("."); + /* Om 'd' INTE är sant (! = inte sant) */ + if (!d) + { + printf("Kan inte läsa aktuell katalog\n"); + return 1; + } + + /* Behandla arugment */ + if (argc == 1) + { + strncpy(opt, "-a", 3); + } + else if (argc == 2) + { + strncpy(opt, argv[1], 3); + + /* Hjälptext */ + if ( strcmp(opt, "-h") == 0 ) + printUsage(argv[0]); + + /* Visa endast filer */ + else if ( strcmp(opt, "-f") == 0 ) + { + typ = S_IFREG; + } + + /* Visa endast kataloger */ + else if ( strcmp(opt, "-d") == 0 ) + { + typ = S_IFDIR; + } + + /* Visa alla filer */ + else if ( strcmp(opt, "-a") == 0 ) + { + ; + } + + /* Om vi angav ett felaktigt argument */ + else + { + printUsage(argv[0]); + return 1; + } + } + /* Om vi angav fel antal argument */ + else + { + printUsage(argv[0]); + return 1; + } + + /* Skriv ut innehållet i katalogen */ + while ((dir = readdir(d)) != NULL) + { + if ( strcmp(opt, "-a") == 0 ) + { + printf("%s\n", dir->d_name); + } + else + { + stat(dir->d_name, &s); + /* Se kapitlet om 'Bitvisa operationer' */ + if ((s.st_mode & S_IFMT) == typ) + printf("%s\n", dir->d_name); + } + } + + /* Stäng "d" och returnera noll */ + closedir(d); + return 0; +} + +void printUsage(char *arg) +{ + printf("Usage: %s [-a] [-f] [-d]\n" + " -a to list all types (default)\n" + " -f to list only files\n" + " -d to list only directories\n", arg); +} diff --git a/kapitel11/simple-ls-ver2.c b/kapitel11/simple-ls-ver2.c new file mode 100644 index 0000000..5a031ab --- /dev/null +++ b/kapitel11/simple-ls-ver2.c @@ -0,0 +1,75 @@ +#define _XOPEN_SOURCE 500 +#include +#include +#include +#include + +void printUsage(char *arg); + +int main(int argc, char **argv) +{ + int opt; + unsigned int typ = 0; + char *path = "."; + + /* Skapa pekare och struct */ + DIR *d; + struct dirent *dir; + struct stat s; + + /* Behandla argument med getopt */ + while ((opt = getopt(argc, argv, "hafdp:")) != -1) + { + switch (opt) + { + case 'a': + typ = -1; + break; + case 'f': + typ = S_IFREG; + break; + case 'd': + typ = S_IFDIR; + break; + case 'p': + path = optarg; + break; + case 'h': + printUsage(argv[0]); + return 0; + default: + printUsage(argv[0]); + return 1; + } + } + + /* Byt katalog med chdir() för att stat() ska + se filerna i rätt katalog */ + chdir(path); + + d = opendir(path); + while ((dir = readdir(d)) != NULL) + { + if ( typ == 0 ) + { + printf("%s\n", dir->d_name); + } + else + { + stat(dir->d_name, &s); + /* Se kapitlet om 'Bitvisa operationer' */ + if ((s.st_mode & S_IFMT) == typ) + printf("%s\n", dir->d_name); + } + } + return 0; +} + +void printUsage(char *arg) +{ + printf("Usage: %s [-a] [-f] [-d] [-p path]\n" + " -a to list all types (default)\n" + " -f to list only files\n" + " -d to list only directories\n" + " -p to specify a directory\n", arg); +} diff --git a/kapitel12/fildesc-ex1.c b/kapitel12/fildesc-ex1.c new file mode 100644 index 0000000..79a79d8 --- /dev/null +++ b/kapitel12/fildesc-ex1.c @@ -0,0 +1,37 @@ +#include +#include +#include +#include +#include + +int main(void) +{ + int fd; + int readstat; + off_t filesize; + struct stat fileinfo; + char wbuf[] = "Hejsan svejsan\n"; + char rbuf[50]; + + /* Öppna filen "minfil" i läs- och skrivläge (O_RDWR). + Skapa den om den inte redan finns (O_CREAT) + Sätt filrättigheterna till 00644*/ + fd = open("minfil", O_CREAT|O_RDWR, 00644); + write(fd, wbuf, sizeof(wbuf)); /* Skriv wbuf till filen */ + + /* Här börjar vi läsa in filen igen */ + fstat(fd, &fileinfo); + filesize = fileinfo.st_size; + printf("Storlek: %ld\n", (long int)filesize); + /* Återställ markören till byte 0 med lseek */ + lseek(fd, 0, SEEK_SET); + readstat = read(fd, rbuf, filesize); /* Läs innehållet till rbuf */ + rbuf[fileinfo.st_size+1] = '\0'; /* Avsluta med NULL */ + + /* Skriv ut information och filens innehåll */ + printf("Fildeskriptorns nummer: %d\n", fd); + printf("Returvärde från 'read': %d\n", readstat); + printf("Inläst text: %s\n", rbuf); + + return 0; +} diff --git a/kapitel12/fseek-ex1.c b/kapitel12/fseek-ex1.c new file mode 100644 index 0000000..6c03bae --- /dev/null +++ b/kapitel12/fseek-ex1.c @@ -0,0 +1,43 @@ +#include + +int main(void) +{ + int langd, bredd, hojd; + signed char ch; + int i; + FILE *fp; + + /* Kontrollera först om filen finns och om inte + avsluta programmet och skriv ett felmeddelande */ + if ( (fp = fopen("konfigfil.txt", "r")) == 0) + { + printf("Filen finns inte!\n"); + return 1; + } + + printf("Position innan läsning: %ld\n", ftell(fp)); + fscanf( fp, "längd: %d, bredd: %d, höjd: %d", + &langd, &bredd, &hojd); + + printf("Lådan har en volym på %d cm3\n", + (langd * bredd * hojd)); + printf("Position efter läsning: %ld\n\n", ftell(fp)); + + printf("Läs tre byte från åttonde byten från starten:\n"); + fseek(fp, 8, SEEK_SET); + for (i = 0; i<3; i++) + { + ch = fgetc(fp); + putchar(ch); + } + printf("\nAktuell position: %ld\n\n", ftell(fp)); + + printf("Flyttar markören 5 bytes framåt och läser resten:\n"); + fseek(fp, 5, SEEK_CUR); + printf("Aktuell position: %ld\n", ftell(fp)); + while ((ch = fgetc(fp)) != EOF) + putchar(ch); + printf("\nAktuell position: %ld\n\n", ftell(fp)); + + return 0; +} diff --git a/kapitel12/konfigfil.txt b/kapitel12/konfigfil.txt new file mode 100644 index 0000000..b2ef628 --- /dev/null +++ b/kapitel12/konfigfil.txt @@ -0,0 +1 @@ +längd: 33, bredd: 20, höjd: 10 diff --git a/kapitel12/lagerhantering-komplett.c b/kapitel12/lagerhantering-komplett.c new file mode 100644 index 0000000..3f35f06 --- /dev/null +++ b/kapitel12/lagerhantering-komplett.c @@ -0,0 +1,360 @@ +#define _XOPEN_SOURCE 500 +#include +#include +#include +#include + +/* Makron */ +#define NAMEMAXLENGTH 30 + +/* Globala variabler så att de är tillgängliga både + från main() och de övriga funktionerna. + struct myData används t.ex. både från main() och + new() */ +struct myData +{ + char name[NAMEMAXLENGTH]; + int quantity; + float price; +}; + +char filename[] = "storage.bin"; + +/* Funktionsprototyper */ +void list(struct myData *datap, int numRec); +void search(struct myData *datap, int numRec, char *name); +void modify(struct myData *datap, int numRec, char *name); +void delete(struct myData *datap, int numRec, char *name); +int new(struct myData *datap); +void printUsage(char *arg); +void printHeader(void); + + +int main(int argc, char* argv[]) +{ + FILE *fp; /* Filpekare */ + int newart = 0; /* Ska vi skapa en ny artikel? */ + int numRec; /* För antalet för artiklar */ + int create; /* För y/n-fråga */ + int opt; /* För getopt() */ + + /* Skapa en strukturvariabel (en pekare) av struct myData */ + struct myData *data; + + /* Skriv ut hjälptexten och returnera 1 om vi saknar argument */ + if (argc < 2) + { + printUsage(argv[0]); + return 1; + } + + /* Kontrollera om filen finns och är läs- och skrivbar. + Om inte, fråga om vi ska skapa den och börja läsa + in artiklar. access() är ett systemanrop för Unixmiljöer */ + if ( access(filename, R_OK|W_OK) != 0 ) + { + /* Använd fprintf() för att skriva felmeddelanden + till stderr */ + fprintf(stderr, "Could not open %s\n", filename); + printf("Create the file and start adding records? (y/n): "); + create = getchar(); + if ( create == 'y' ) + { + /* Allokera minne för en struct myData och anropa + sedan new() med en pekare till minnet för att lägga + till artiklar i lagret, en i taget */ + numRec = 1; + data = calloc(numRec, sizeof(struct myData)); + new(data); + free(data); + return 0; + } + else + return 1; + } + + /* Öppna filen i läsläge */ + fp = fopen(filename, "rb"); + + /* Läs in befintlig data från filen till strukturen */ + fseek(fp, 0, SEEK_END); + numRec = ftell(fp) / sizeof(struct myData); + data = calloc(numRec, sizeof(struct myData)); + rewind(fp); + fread(data, sizeof(struct myData), numRec, fp); + fclose(fp); + + /* Behandla argumenten med getopt() */ + while ((opt = getopt(argc, argv, "hls:m:d:n")) != -1) + { + switch (opt) + { + case 'l': + list(data, numRec); + break; + case 's': + search(data, numRec, optarg); + break; + case 'm': + modify(data, numRec, optarg); + break; + case 'd': + delete(data, numRec, optarg); + break; + case 'n': + newart = 1; + break; + case 'h': + printUsage(argv[0]); + return 0; + default: + printUsage(argv[0]); + return 1; + } + } + + /* Fortsätt här om filen finns och vi valde att lägga + till artiklar */ + if ( newart == 1 ) + { + data = calloc(1, sizeof(struct myData)); + if ( new(data) == 1 ) + return 1; + } + + /* Här är programmet klart, så frigör minnet och returnera 0 */ + free(data); + return 0; +} + +/* Funktionerna nedan tar en pekare till datatypen struct myData + som första argument. Som andra argument ett heltal som innehåller + antalet artiklar i lagret. */ +void list(struct myData *datap, int numRec) +{ + int i; + printHeader(); + for (i = 0; iname, NAMEMAXLENGTH, stdin); + datap->name[strcspn(datap->name, "\n")] = '\0'; + + if ( strcmp(datap->name, "done") == 0 ) + { + fclose(fp); + return 0; + } + printf("Quantity: "); scanf("%d", &datap->quantity); + printf("Price: "); scanf("%f", &datap->price); + bytes = fwrite(datap, sizeof(struct myData), 1, fp); + if (bytes != 1) + { + fprintf(stderr, "Could not write to the file!\n"); + return 1; + } + } +} + +void printUsage(char *arg) +{ + fprintf(stderr, "Usage: %s [-l] [-s name] " + "[-m name] \n" + "[-d name] [-n] [-h]\n\n" + "-l = list the articles in the database\n" + "-s name = search for an article named 'name'\n" + "-m name = modify the article named 'name'\n" + " You'll then have the choice to change name, quantity " + "and price.\n" + "-d name = delete the article named 'name'\n" + "-n = create new articles (interactive mode only)\n" + "-h = display this help message\n", arg); +} + +void printHeader(void) +{ + int i; + printf("\n%-30s\t", "Name"); + printf("%s\t", "Quantity"); + printf("%s\t\n", "Price"); + for (i = 0; i<=52; i++) + printf("="); + printf("\n"); +} diff --git a/kapitel12/las-flera-flt.c b/kapitel12/las-flera-flt.c new file mode 100644 index 0000000..afe2c50 --- /dev/null +++ b/kapitel12/las-flera-flt.c @@ -0,0 +1,23 @@ +#include + +int main(void) +{ + /* Korrekt storlek från början på x & y */ + float y[3]; + int x[3]; + int i; + FILE *fp; + if ( (fp = fopen("test.bin", "rb")) == 0 ) + { + fprintf(stderr, "Kan inte öppna filen\n"); + return 1; + } + fread(&y, sizeof(y), 1, fp); /* Först flyttalen */ + fread(&x, sizeof(x), 1, fp); /* Sen heltalen... */ + for (i = 0; i<3; i++) + printf("%f\n", y[i]); + + for (i = 0; i<3; i++) + printf("%d\n", x[i]); + return 0; +} diff --git a/kapitel12/las-flt-fil-ex1.c b/kapitel12/las-flt-fil-ex1.c new file mode 100644 index 0000000..fad35c8 --- /dev/null +++ b/kapitel12/las-flt-fil-ex1.c @@ -0,0 +1,25 @@ +#include + +int main(void) +{ + float y[10]; + int bytes, antal, i; + FILE *fp; + if ( (fp = fopen("test.bin", "rb")) == 0) + { + fprintf(stderr, "Kan inte öppna filen\n"); + return 1; + } + fseek(fp, 0, SEEK_END); /* Flytt till slutet av filen*/ + bytes = ftell(fp); /* Totala antalet bytes */ + rewind(fp); /* Flytta markören till början av filen */ + printf("Antal bytes i filen: %d\n", bytes); + antal = bytes / sizeof(float); /* Hur många element */ + printf("Antal element: %d\n", antal); + fread(&y, sizeof(float), antal, fp); + /* Skriv ut alla flyttalen från filen */ + for (i = 0; i + +int main(void) +{ + float y[3]; + int i; + FILE *fp; + if ( (fp = fopen("test.bin", "rb")) == 0 ) + { + fprintf(stderr, "Kan inte öppna filen\n"); + return 1; + } + fread(&y, sizeof(y), 1, fp); + for (i = 0; i<3; i++) + printf("%f\n", y[i]); + fclose(fp); + return 0; +} diff --git a/kapitel12/lasa-bin-ex1.c b/kapitel12/lasa-bin-ex1.c new file mode 100644 index 0000000..e776596 --- /dev/null +++ b/kapitel12/lasa-bin-ex1.c @@ -0,0 +1,16 @@ +#include + +int main(void) +{ + FILE *binfil; + float x; + if ( (binfil = fopen("flyttal.bin", "rb")) == 0 ) + { + fprintf(stderr, "Kunde inte öppna filen\n"); + return 1; + } + fread(&x, sizeof(x), 1, binfil); + printf("Flyttalet är: %f\n", x); + fclose(binfil); + return 0; +} diff --git a/kapitel12/lasa-fil-ex1.c b/kapitel12/lasa-fil-ex1.c new file mode 100644 index 0000000..4a4bac2 --- /dev/null +++ b/kapitel12/lasa-fil-ex1.c @@ -0,0 +1,14 @@ +#include + +int main(void) +{ + FILE *fp; + signed char c; + + fp = fopen("test.txt", "r"); + while ((c = getc(fp)) != EOF) + putchar(c); + fclose(fp); + + return 0; +} diff --git a/kapitel12/lasa-fil-ex2.c b/kapitel12/lasa-fil-ex2.c new file mode 100644 index 0000000..ba4e39c --- /dev/null +++ b/kapitel12/lasa-fil-ex2.c @@ -0,0 +1,32 @@ +#include +#include + +int main(void) +{ + FILE *fp; + int strSize, readSize; + char *buffer; + fp = fopen("test.txt", "r"); + + /* Ta reda på storleken och återgå sen till start */ + fseek(fp, 0, SEEK_END); + strSize = ftell(fp); + rewind(fp); + + /* Skapa dynamiskt minne för filens innehåll */ + buffer = calloc(sizeof(char), strSize+1); + + /* Läs in filens innehåll och spara antalet inlästa + tecken i 'readSize' */ + readSize = fread(buffer, sizeof(char), strSize, fp); + + fclose(fp); /* Vi är klara med fp så stäng den */ + + printf("%s\n\n", buffer); + printf("Storleken är %d tecken och vi läste in %d tecken\n", + strSize, readSize); + + free(buffer); /* Frigör det dynamiska minnet */ + + return 0; +} diff --git a/kapitel12/lasa-fil-ex3-c99.c b/kapitel12/lasa-fil-ex3-c99.c new file mode 100644 index 0000000..af7ed62 --- /dev/null +++ b/kapitel12/lasa-fil-ex3-c99.c @@ -0,0 +1,33 @@ +#define _XOPEN_SOURCE 600 +#include +#include +#include +#include +#include +#include + +int main(void) +{ + FILE *fp; + off_t filesize; + int fd, readSize; + struct stat fileinfo; + char* buffer; + fp = fopen("test.txt", "r"); + + fd = fileno(fp); /* Hämta fildeskriptorn och spara i fd */ + fstat(fd, &fileinfo); /* Hämta all information till 'fileinfo' */ + filesize = fileinfo.st_size; /* Spara filens storlek i filesize */ + /* från 'fileinfo.st_size' */ + + buffer = calloc(sizeof(char), filesize+1); + readSize = fread(buffer, sizeof(char), filesize, fp); + buffer[filesize] = '\0'; + + printf("%s\n\n", buffer); + printf("Fildeskriptor: %d\n", fd); + printf("Filens storlek är %jd byte och vi har läst in %d byte\n", + (intmax_t)filesize, readSize); + + return 0; +} diff --git a/kapitel12/lasa-fil-ex3.c b/kapitel12/lasa-fil-ex3.c new file mode 100644 index 0000000..c67300a --- /dev/null +++ b/kapitel12/lasa-fil-ex3.c @@ -0,0 +1,32 @@ +#define _XOPEN_SOURCE 500 +#include +#include +#include +#include +#include + +int main(void) +{ + FILE *fp; + off_t filesize; + int fd, readSize; + struct stat fileinfo; + char* buffer; + fp = fopen("test.txt", "r"); + + fd = fileno(fp); /* Hämta fildeskriptorn och spara i fd */ + fstat(fd, &fileinfo); /* Hämta all information till 'fileinfo' */ + filesize = fileinfo.st_size; /* Spara filens storlek i filesize */ + /* från 'fileinfo.st_size' */ + + buffer = calloc(sizeof(char), filesize+1); + readSize = fread(buffer, sizeof(char), filesize, fp); + buffer[filesize] = '\0'; + + printf("%s\n\n", buffer); + printf("Fildeskriptor: %d\n", fd); + printf("Filens storlek är %ld byte och vi har läst in %d byte\n", + (long int)filesize, readSize); + + return 0; +} diff --git a/kapitel12/lasa-matt.c b/kapitel12/lasa-matt.c new file mode 100644 index 0000000..bda2ccf --- /dev/null +++ b/kapitel12/lasa-matt.c @@ -0,0 +1,27 @@ +#include + +int main(void) +{ + int langd, bredd, hojd; + FILE *fp; + + /* Kontrollera först om filen finns och om inte + avsluta programmet och skriv ett felmeddelande */ + if ( (fp = fopen("konfigfil.txt", "r")) == 0) + { + printf("Filen finns inte!\n"); + return 1; + } + + /* Läs in de olika "fälten" från filen till rätt + variabel */ + fscanf( fp, "längd: %d, bredd: %d, höjd: %d", + &langd, &bredd, &hojd); + + /* Skriv ut volymen */ + printf("Lådan har en volym på %d cm3\n", + (langd * bredd * hojd)); + + return 0; + +} diff --git a/kapitel12/lasa-person-struct.c b/kapitel12/lasa-person-struct.c new file mode 100644 index 0000000..96c89b8 --- /dev/null +++ b/kapitel12/lasa-person-struct.c @@ -0,0 +1,38 @@ +#include +#include + +#define MAXLANGD 30 +#define ANTAL 3 + +int main(void) +{ + FILE *fp; + int i; + struct minData + { + char fnamn[MAXLANGD]; + char enamn[MAXLANGD]; + int alder; + }; + + struct minData personer[ANTAL]; + + if ( (fp= fopen("personer.bin", "rb")) == 0 ) + { + fprintf(stderr, "Kan inte öppna filen\n"); + return 1; + } + + /* Läs in strukturen från filen */ + fread(personer, sizeof(struct minData), ANTAL, fp); + + /* Loopa igenom alla personer i strukturen */ + for (i = 0; i + +int main(void) +{ + FILE *binfil; + float x; + /* Kontrollera om fopen lyckades öppna filen + i skrivläge */ + if ( (binfil = fopen("flyttal.bin", "wb")) == 0 ) + { + /* Skriv felmeddelande till stderr */ + fprintf(stderr, "Kan inte skriva till fil\n"); + return 1; + } + printf("Skriv ett flyttal: "); + scanf("%f", &x); + fwrite(&x, sizeof(x), 1, binfil); + fclose(binfil); + return 0; +} diff --git a/kapitel12/skriv-fil-ex1.c b/kapitel12/skriv-fil-ex1.c new file mode 100644 index 0000000..ff26509 --- /dev/null +++ b/kapitel12/skriv-fil-ex1.c @@ -0,0 +1,18 @@ +#include + +int main(void) +{ + FILE *fp; + char namn1[] = "Knatte"; + char namn2[] = "Fnatte"; + + fp = fopen("test.txt", "w"); + + fprintf(fp, "%s, %s och Tjatte\n" + "bor alla i Ankeborg.\n\n", namn1, namn2); + fputs("Kalle och Lisa bor också i Ankeborg.\n", fp); + + fclose(fp); + + return 0; +} diff --git a/kapitel12/skriv-flera-flt.c b/kapitel12/skriv-flera-flt.c new file mode 100644 index 0000000..36bb604 --- /dev/null +++ b/kapitel12/skriv-flera-flt.c @@ -0,0 +1,18 @@ +#include + +int main(void) +{ + float y[3] = {3.14, 5.55, 9.56}; + int x[3] = {99, 101, 105}; + FILE *fp; + if ( (fp = fopen("test.bin", "wb")) == 0 ) + { + fprintf(stderr, "Kan inte läsa filen\n"); + return 1; + } + + fwrite(&y, sizeof(y), 1, fp); + fwrite(&x, sizeof(x), 1, fp); + fclose(fp); + return 0; +} diff --git a/kapitel12/skriv-flt-fil.c b/kapitel12/skriv-flt-fil.c new file mode 100644 index 0000000..38a39b0 --- /dev/null +++ b/kapitel12/skriv-flt-fil.c @@ -0,0 +1,15 @@ +#include + +int main(void) +{ + float y[3] = {3.14, 5.55, 9.56}; + FILE *fp; + if ( (fp = fopen("test.bin", "wb")) == 0 ) + { + fprintf(stderr, "Kan inte öppna filen\n"); + return 1; + } + fwrite(&y, sizeof(y), 1, fp); + fclose(fp); + return 0; +} diff --git a/kapitel12/skriv-person-struct.c b/kapitel12/skriv-person-struct.c new file mode 100644 index 0000000..aa18d95 --- /dev/null +++ b/kapitel12/skriv-person-struct.c @@ -0,0 +1,42 @@ +#include +#include + +#define MAXLANGD 30 +#define ANTAL 3 + +int main(void) +{ + FILE *fp; + struct minData + { + char fnamn[MAXLANGD]; + char enamn[MAXLANGD]; + int alder; + }; + + struct minData personer[ANTAL]; + + if ( (fp = fopen("personer.bin", "wb")) == 0 ) + { + fprintf(stderr, "Kan inte öppna filen\n"); + return 1; + } + + /* Skapa tre person i strukturen */ + strcpy(personer[0].fnamn, "Kalle"); + strcpy(personer[0].enamn, "Anka"); + personer[0].alder = 31; + + strcpy(personer[1].fnamn, "Lisa"); + strcpy(personer[1].enamn, "Anka"); + personer[1].alder = 28; + + strcpy(personer[2].fnamn, "Fnatte"); + strcpy(personer[2].enamn, "Anka"); + personer[2].alder = 8; + + /* Skriv ut strukturen till en fil */ + fwrite(personer, sizeof(struct minData), ANTAL, fp); + + return 0; +} diff --git a/kapitel13/filinfo-portabel.c b/kapitel13/filinfo-portabel.c new file mode 100644 index 0000000..9663275 --- /dev/null +++ b/kapitel13/filinfo-portabel.c @@ -0,0 +1,39 @@ +#include +#include +#include +#include +#if __STDC_VERSION__ >= 199901L +#define C99 +#include +#endif + +int main(int argc, char *argv[]) +{ + struct stat fileinfo; + if (argc != 2) + { + fprintf(stderr, "Usage: %s path/to/file\n", argv[0]); + return 1; + } + + stat(argv[1], &fileinfo); + + #ifdef C99 + printf("C99 (or newer)\n"); + printf("Inode number: %ju\n", + (uintmax_t)fileinfo.st_ino); + printf("Size in bytes: %jd (%.2f kilobytes)\n", + (intmax_t)fileinfo.st_size, + (double)fileinfo.st_size / 1024); + #else + printf("C89\n"); + printf("Inode number: %lu\n", (unsigned long int)fileinfo.st_ino); + printf("Size in bytes: %lu (%.2f kilobytes)\n", + (unsigned long int)fileinfo.st_size, + (float)fileinfo.st_size / 1024); + #endif + printf("User-ID: %d\n", fileinfo.st_uid); + printf("Group-ID: %d\n", fileinfo.st_gid); + + return 0; +} diff --git a/kapitel13/filinfo.c b/kapitel13/filinfo.c new file mode 100644 index 0000000..af7c82f --- /dev/null +++ b/kapitel13/filinfo.c @@ -0,0 +1,25 @@ +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + struct stat fileinfo; + if (argc != 2) + { + fprintf(stderr, "Usage: %s path/to/file\n", argv[0]); + return 1; + } + + stat(argv[1], &fileinfo); + + printf("Inode number: %lu\n", (unsigned long int)fileinfo.st_ino); + printf("Size in bytes: %lu (%.2f kilobytes)\n", + (unsigned long int)fileinfo.st_size, + (float)fileinfo.st_size / 1024); + printf("User-ID: %d\n", fileinfo.st_uid); + printf("Group-ID: %d\n", fileinfo.st_gid); + + return 0; +} diff --git a/kapitel13/mychown-felhantering-ex1.c b/kapitel13/mychown-felhantering-ex1.c new file mode 100644 index 0000000..50cfeeb --- /dev/null +++ b/kapitel13/mychown-felhantering-ex1.c @@ -0,0 +1,42 @@ +#define _XOPEN_SOURCE 500 +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + uid_t uid; + gid_t gid; + + if (argc != 4) + { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + + uid = (uid_t)atoi(argv[2]); + gid = (gid_t)atoi(argv[3]); + + if (chown(argv[1], uid, gid) == -1) + { + switch (errno) + { + case EPERM: + fprintf(stderr, "Operation not permitted\n"); + break; + case ENOENT: + fprintf(stderr, "No such file or directory\n"); + break; + case ENAMETOOLONG: + fprintf(stderr, "Filename too long\n"); + break; + default: + fprintf(stderr, "Unknown error\n"); + break; + } + return 1; + } + + return 0; +} diff --git a/kapitel13/mychown-felhantering-ex2.c b/kapitel13/mychown-felhantering-ex2.c new file mode 100644 index 0000000..05682db --- /dev/null +++ b/kapitel13/mychown-felhantering-ex2.c @@ -0,0 +1,30 @@ +#define _XOPEN_SOURCE 500 +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + uid_t uid; + gid_t gid; + + if (argc != 4) + { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + + uid = (uid_t)atoi(argv[2]); + gid = (gid_t)atoi(argv[3]); + + if (chown(argv[1], uid, gid) == -1) + { + printf("%i\n", errno); /* Visar vad errno innehåller */ + printf("%s\n", strerror(errno)); /* Meddelandet i klartext */ + return 1; + } + + return 0; +} diff --git a/kapitel13/mychown-felhantering-ex3.c b/kapitel13/mychown-felhantering-ex3.c new file mode 100644 index 0000000..7d9c582 --- /dev/null +++ b/kapitel13/mychown-felhantering-ex3.c @@ -0,0 +1,27 @@ +#define _XOPEN_SOURCE 500 +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + uid_t uid; + gid_t gid; + + if (argc != 4) + { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + + uid = (uid_t)atoi(argv[2]); + gid = (gid_t)atoi(argv[3]); + + if (chown(argv[1], uid, gid) == -1) + { + perror("chown"); + return 1; + } + return 0; +} diff --git a/kapitel13/mychown.c b/kapitel13/mychown.c new file mode 100644 index 0000000..4b90ad9 --- /dev/null +++ b/kapitel13/mychown.c @@ -0,0 +1,27 @@ +#define _XOPEN_SOURCE 500 +#include +#include +#include + +int main(int argc, char *argv[]) +{ + uid_t uid; + gid_t gid; + + if (argc != 4) + { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + + uid = (uid_t)atoi(argv[2]); + gid = (gid_t)atoi(argv[3]); + + if (chown(argv[1], uid, gid) == -1) + { + fprintf(stderr, "Could not change UID or GID\n"); + return 1; + } + + return 0; +} diff --git a/kapitel13/mytouch.c b/kapitel13/mytouch.c new file mode 100644 index 0000000..ca88b40 --- /dev/null +++ b/kapitel13/mytouch.c @@ -0,0 +1,22 @@ +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + if (argc != 2) + { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + /* Rättigheterna nedan blir 644, Read/Write user, + Read group, Read others */ + creat(argv[1], S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + if (errno != 0) + { + perror("creat"); + return 1; + } + return 0; +} diff --git a/kapitel13/write-ex1.c b/kapitel13/write-ex1.c new file mode 100644 index 0000000..d406854 --- /dev/null +++ b/kapitel13/write-ex1.c @@ -0,0 +1,8 @@ +#include +#include + +int main(void) +{ + write(1, "Hejsan\n", 7); + return 0; +} diff --git a/kapitel13/write-ex2.c b/kapitel13/write-ex2.c new file mode 100644 index 0000000..08340d6 --- /dev/null +++ b/kapitel13/write-ex2.c @@ -0,0 +1,8 @@ +#include +#include + +int main(void) +{ + write(STDOUT_FILENO, "Hejsan\n", 7); + return 0; +} diff --git a/kapitel14/fahr-felhantering.c b/kapitel14/fahr-felhantering.c new file mode 100644 index 0000000..3c7fd93 --- /dev/null +++ b/kapitel14/fahr-felhantering.c @@ -0,0 +1,40 @@ +#include +#include +#include + +/* Funktionsprototyp av isNumeric */ +int isNumeric(const char *str); + +int main(void) +{ + char c[10]; + float cels, f; + while(fgets(c, sizeof(c), stdin) != NULL) + { + if (isNumeric(c)) + { + cels = atof(c); /* char till float (stdlib.h) */ + f = cels*9/5+32; + printf("%.1f\n", f); + } + else + { + fprintf(stderr, "Påträffade icke-numeriskt värde\n"); + return 1; + } + } + return 0; +} + +/* Funktionen för att kontrollera inmatade tecken */ +int isNumeric(const char *str) +{ + if(strspn(str, "0123456789.-\n") == strlen(str)) /*string.h*/ + { + return 1; + } + else + { + return 0; + } +} diff --git a/kapitel14/fahr.c b/kapitel14/fahr.c new file mode 100644 index 0000000..24f1244 --- /dev/null +++ b/kapitel14/fahr.c @@ -0,0 +1,15 @@ +#include +#include + +int main(void) +{ + char c[10]; + float cels, f; + while(fgets(c, sizeof(c), stdin) != NULL) + { + cels = atof(c); /* gör om char till float (stdlib.h) */ + f = cels*9/5+32; + printf("%.1f\n", f); + } + return 0; +} diff --git a/kapitel14/miljovar-ex1.c b/kapitel14/miljovar-ex1.c new file mode 100644 index 0000000..9d2875d --- /dev/null +++ b/kapitel14/miljovar-ex1.c @@ -0,0 +1,29 @@ +#include +#include +#include + +int main(void) +{ + /* Spara ett värde för senare användning */ + const char* myhome = getenv("HOME"); + + /* Skriv ut några miljövariabler */ + printf("Ditt UID är: %i\n", getuid()); + printf("Ditt GID är: %i\n", getgid()); + printf("Ditt användarnamn är: %s\n", getenv("USER")); + printf("Det aktuella programmet heter: %s\n", getenv("_")); + + printf("Din hemkatalog är: %s\n", myhome); + + /* Testa om en variabel är satt eller inte */ + if (getenv("DISPLAY")) + { + printf("Du använder X-Window just nu\n"); + } + else + { + printf("Du använder inte X-Window just nu\n"); + } + + return 0; +} diff --git a/kapitel14/miljovar-ex2.c b/kapitel14/miljovar-ex2.c new file mode 100644 index 0000000..13f7374 --- /dev/null +++ b/kapitel14/miljovar-ex2.c @@ -0,0 +1,11 @@ +#define _XOPEN_SOURCE 600 +#include +#include + +int main(void) +{ + setenv("MINVAR", "J-B", 0); /* sätt variabeln (0 = skriv ej + över ev. befintlig variabel) */ + printf("%s\n", getenv("MINVAR")); /* testa om det fungerade */ + return 0; +} diff --git a/kapitel14/outerrtest.c b/kapitel14/outerrtest.c new file mode 100644 index 0000000..c48a2a9 --- /dev/null +++ b/kapitel14/outerrtest.c @@ -0,0 +1,8 @@ +#include + +int main(void) +{ + fprintf(stdout, "Text till stdout\n"); + fprintf(stderr, "Ett felmeddelande\n"); + return 0; +} diff --git a/kapitel14/temps.txt b/kapitel14/temps.txt new file mode 100644 index 0000000..ea6d05f --- /dev/null +++ b/kapitel14/temps.txt @@ -0,0 +1,5 @@ +22 +23 +25 +30 +31 diff --git a/kapitel14/testtmp.txt b/kapitel14/testtmp.txt new file mode 100644 index 0000000..d15a782 --- /dev/null +++ b/kapitel14/testtmp.txt @@ -0,0 +1,10 @@ +id=151 temperature=-4.6 humidity=92 time=2016-11-13 22:50:20 +id=167 temperature=22.1 humidity=20 time=2016-11-13 22:49:34 +id=151 temperature=-4.6 humidity=92 time=2016-11-13 22:53:32 +id=167 temperature=22.0 humidity=20 time=2016-11-13 22:53:34 +id=151 temperature=-4.6 humidity=92 time=2016-11-13 22:56:44 +id=167 temperature=22.3 humidity=20 time=2016-11-13 22:56:45 +id=151 temperature=-4.7 humidity=92 time=2016-11-13 22:59:56 +id=167 temperature=22.4 humidity=20 time=2016-11-13 22:59:57 +id=151 temperature=-4.7 humidity=92 time=2016-11-13 23:02:20 +id=167 temperature=22.4 humidity=20 time=2016-11-13 23:02:21 diff --git a/kapitel15/exempel.c b/kapitel15/exempel.c new file mode 100644 index 0000000..57efab2 --- /dev/null +++ b/kapitel15/exempel.c @@ -0,0 +1,11 @@ +#include + +int main(void) +{ + int x, y; + x = 5; + + printf("x = %d\n", x); + printf("Adressen till x är %lu\n", &x); + return 0; +} diff --git a/kapitel15/funk.c b/kapitel15/funk.c new file mode 100644 index 0000000..aaa7ced --- /dev/null +++ b/kapitel15/funk.c @@ -0,0 +1,4 @@ +int kvadrat(int n) +{ + return n*n; +} diff --git a/kapitel15/funk.h b/kapitel15/funk.h new file mode 100644 index 0000000..f6cab38 --- /dev/null +++ b/kapitel15/funk.h @@ -0,0 +1 @@ +int kvadrat(int n); diff --git a/kapitel15/jbmath/jbmath.c b/kapitel15/jbmath/jbmath.c new file mode 100644 index 0000000..a87cfb9 --- /dev/null +++ b/kapitel15/jbmath/jbmath.c @@ -0,0 +1,10 @@ +float circumf(float diameter) +{ + const float pi = 3.14159265; + return (pi * diameter); +} + +float area(float length, float height) +{ + return (length * height); +} diff --git a/kapitel15/jbmath/jbmath.h b/kapitel15/jbmath/jbmath.h new file mode 100644 index 0000000..171e5ef --- /dev/null +++ b/kapitel15/jbmath/jbmath.h @@ -0,0 +1,3 @@ +float circumf(float diameter); +float area(float length, float height); +long jbpow(int x, int n); diff --git a/kapitel15/jbmath/jbpow.c b/kapitel15/jbmath/jbpow.c new file mode 100644 index 0000000..9bf1874 --- /dev/null +++ b/kapitel15/jbmath/jbpow.c @@ -0,0 +1,10 @@ +long jbpow(int x, int n) +{ + long num = 1; + int i; + for(i = 0; i +#include + +int main(void) +{ + printf("En cirkel med diametern 5.5 har omkretsen %.3f\n", + circumf(5.5)); + printf("En rektangel med sidorna 3 och 8.5 har arean %.3f\n", + area(3, 8.5)); + printf("5 upphöjt till 6 är %ld\n", jbpow(5, 6)); + return 0; +} diff --git a/kapitel15/jbmath/usemath.c b/kapitel15/jbmath/usemath.c new file mode 100644 index 0000000..32799d9 --- /dev/null +++ b/kapitel15/jbmath/usemath.c @@ -0,0 +1,12 @@ +#include +#include "jbmath.h" + +int main(void) +{ + printf("En cirkel med diametern 5.5 har omkretsen %.3f\n", + circumf(5.5)); + printf("En rektangel med sidorna 3 och 8.5 har arean %.3f\n", + area(3, 8.5)); + printf("5 upphöjt till 6 är %ld\n", jbpow(5, 6)); + return 0; +} diff --git a/kapitel15/matte/Makefile b/kapitel15/matte/Makefile new file mode 100644 index 0000000..3801ac3 --- /dev/null +++ b/kapitel15/matte/Makefile @@ -0,0 +1,17 @@ +CC=cc +CFLAGS=-Wall -Wextra -pedantic -std=c99 -D_XOPEN_SOURCE=600 + +matte: matte.o minmattefunk.o usage.o + $(CC) -o matte matte.o minmattefunk.o usage.o + +matte.o: matte.c minmattefunk.h usage.h + $(CC) $(CFLAGS) -c matte.c + +minmattefunk.o: minmattefunk.c + $(CC) $(CFLAGS) -c minmattefunk.c + +usage.o: usage.c + $(CC) $(CFLAGS) -c usage.c + +clean: + rm matte minmattefunk.o matte.o usage.o diff --git a/kapitel15/matte/matte.c b/kapitel15/matte/matte.c new file mode 100644 index 0000000..d49753d --- /dev/null +++ b/kapitel15/matte/matte.c @@ -0,0 +1,34 @@ +#include +#include +#include +#include "minmattefunk.h" +#include "usage.h" + +int main(int argc, char **argv) +{ + int opt; + if (argc == 1) + { + printUsage(argv[0]); + return 1; + } + + while ((opt = getopt(argc, argv, "s:c:")) != -1) + { + switch (opt) + { + case 's': + printf("%d squared is %d\n", atoi(optarg), + kvadrat(atoi(optarg))); + break; + case 'c': + printf("%d cubed is %d \n", atoi(optarg), + kubik(atoi(optarg))); + break; + default: + printUsage(argv[0]); + return 1; + } + } + return 0; +} diff --git a/kapitel15/matte/minmattefunk.c b/kapitel15/matte/minmattefunk.c new file mode 100644 index 0000000..71c8fd8 --- /dev/null +++ b/kapitel15/matte/minmattefunk.c @@ -0,0 +1,9 @@ +int kvadrat(int x) +{ + return x*x; +} + +int kubik(int x) +{ + return x*x*x; +} diff --git a/kapitel15/matte/minmattefunk.h b/kapitel15/matte/minmattefunk.h new file mode 100644 index 0000000..41c0f1b --- /dev/null +++ b/kapitel15/matte/minmattefunk.h @@ -0,0 +1,2 @@ +int kvadrat(int x); +int kubik(int x); diff --git a/kapitel15/matte/usage.c b/kapitel15/matte/usage.c new file mode 100644 index 0000000..c6ce378 --- /dev/null +++ b/kapitel15/matte/usage.c @@ -0,0 +1,8 @@ +#include + +void printUsage(char *arg) +{ + printf("Usage: %s (-s) | (-c) (integer)\n" + "-s = calculate the square of an integer\n" + "-c = calculate the cube of an integer\n", arg); +} diff --git a/kapitel15/matte/usage.h b/kapitel15/matte/usage.h new file mode 100644 index 0000000..18b3f0c --- /dev/null +++ b/kapitel15/matte/usage.h @@ -0,0 +1 @@ +void printUsage(char *arg); diff --git a/kapitel15/matte/version2.Makefile b/kapitel15/matte/version2.Makefile new file mode 100644 index 0000000..9b2d240 --- /dev/null +++ b/kapitel15/matte/version2.Makefile @@ -0,0 +1,10 @@ +CC=cc +CFLAGS=-Wall -Wextra -pedantic -std=c99 -D_XOPEN_SOURCE=600 + +matte: matte.o minmattefunk.o usage.o + $(CC) -o matte matte.o minmattefunk.o usage.o + +matte.o: minmattefunk.h usage.h + +clean: + rm matte minmattefunk.o matte.o usage.o diff --git a/kapitel15/matte/version3.Makefile b/kapitel15/matte/version3.Makefile new file mode 100644 index 0000000..f4cc30c --- /dev/null +++ b/kapitel15/matte/version3.Makefile @@ -0,0 +1,11 @@ +CC=cc +CFLAGS=-Wall -Wextra -pedantic -std=c99 -D_XOPEN_SOURCE=600 +OBJS=matte.o minmattefunk.o usage.o + +matte: $(OBJS) + $(CC) -o matte $(OBJS) + +matte.o: minmattefunk.h usage.h + +clean: + rm matte $(OBJS) diff --git a/kapitel15/matte/version4.Makefile b/kapitel15/matte/version4.Makefile new file mode 100644 index 0000000..79ddbdf --- /dev/null +++ b/kapitel15/matte/version4.Makefile @@ -0,0 +1,18 @@ +CC=cc +CFLAGS=-Wall -Wextra -pedantic -std=c99 -D_XOPEN_SOURCE=600 +OBJS=matte.o minmattefunk.o usage.o +PREFIX=/usr/local + +matte: $(OBJS) + $(CC) -o matte $(OBJS) + +matte.o: minmattefunk.h usage.h + +clean: + rm matte $(OBJS) + +install: + cp matte $(DESTDIR)$(PREFIX)/bin/matte + +uninstall: + rm $(DESTDIR)$(PREFIX)/bin/matte diff --git a/kapitel15/prog.c b/kapitel15/prog.c new file mode 100644 index 0000000..dce3b66 --- /dev/null +++ b/kapitel15/prog.c @@ -0,0 +1,7 @@ + #include "funk.h" + #define TAL 8 + + int main(void) + { + return kvadrat(TAL); + } diff --git a/kapitel16/daemon-ex1.c b/kapitel16/daemon-ex1.c new file mode 100644 index 0000000..610ebb3 --- /dev/null +++ b/kapitel16/daemon-ex1.c @@ -0,0 +1,66 @@ +#define _XOPEN_SOURCE 500 +#include +#include +#include +#include +#include +int main(void) +{ + pid_t process_id = 0; + pid_t sid = 0; + /* Skapa barn/child process */ + process_id = fork(); + /* Hantera eventuellt fel vid fork() */ + if (process_id < 0) + { + fprintf(stderr, "fork failed!\n"); + exit(1); + } + /* Förälderprocessen/parent process. Avsluta den */ + else if (process_id > 0) + { + exit(0); + } + /* Starta en ny session */ + sid = setsid(); + if(sid < 0) + { + /* Avsluta ifall det inte gick att skapa en ny + session */ + fprintf(stderr, "Failure to set new session\n"); + exit(1); + } + /* Gör en ny fork (dubbel-fork). Detta blir demonen */ + process_id = fork(); + /* Hantera eventuellt fel vid fork() */ + if (process_id < 0) + { + fprintf(stderr, "fork failed!\n"); + exit(1); + } + /* Förälderprocessen/parent process. + Avsluta den eftersom allt arbete kommer att + utföras av demonen. Skriv också ut demonens PID */ + else if (process_id > 0) + { + printf("Daemon process: %d \n", process_id); + exit(0); + } + /* Sätt umask till 022 (rw-r--r-- / rwx-r-xr-x) */ + umask(022); + /* Ändra aktuell katalog till / */ + chdir("/"); + /* Stäng stdin, stdout och stderr och återöppna dem till + /dev/null. Dessa behövs inte i en demonprocess */ + close(STDIN_FILENO); + close(STDOUT_FILENO); + close(STDERR_FILENO); + open("/dev/null", O_RDONLY); /* 0 = stdin */ + open("/dev/null", O_WRONLY); /* 1 = stdout */ + open("/dev/null", O_RDWR); /* 2 = stderr */ + /* Här börjar demonens arbete... */ + for(;;) + { + sleep(5); + } +} diff --git a/kapitel16/execldemo.c b/kapitel16/execldemo.c new file mode 100644 index 0000000..c72e6cf --- /dev/null +++ b/kapitel16/execldemo.c @@ -0,0 +1,12 @@ +#include +#include +#include + +int main(void) +{ + sleep(15); + execl("/usr/bin/man", "man", "ls", (char *)NULL); + perror("execl"); + + return 0; +} diff --git a/kapitel16/forkdemo-ex2.c b/kapitel16/forkdemo-ex2.c new file mode 100644 index 0000000..fdb622c --- /dev/null +++ b/kapitel16/forkdemo-ex2.c @@ -0,0 +1,29 @@ +#define _XOPEN_SOURCE 500 +#include +#include +#include + +int main(void) +{ + pid_t pid; + int status; + pid = fork(); + if (pid == 0) + { + execl("/usr/bin/man", "man", "ls", (char *)NULL); + perror("execl"); + } + else if (pid > 0) + { + waitpid(pid, &status, 0); + printf("Barnet är klart, återgår till förälderprocessen\n"); + printf("Barnet returnerade %i\n", status); + } + else + { + fprintf(stderr, "Något gick fel med fork()\n"); + return 1; + } + + return 0; +} diff --git a/kapitel16/forkdemo.c b/kapitel16/forkdemo.c new file mode 100644 index 0000000..209e22e --- /dev/null +++ b/kapitel16/forkdemo.c @@ -0,0 +1,25 @@ +#define _XOPEN_SOURCE 500 +#include +#include + +int main(void) +{ + pid_t pid; + pid = fork(); + if (pid == 0) + { + printf("Jag är barnprocessen\n"); + sleep(30); + } + else if (pid > 0) + { + printf("Jag är förälderprocessen\n"); + sleep(30); + } + else + { + fprintf(stderr, "Något gick fel med fork()\n"); + return 1; + } + return 0; +} diff --git a/kapitel16/systest.c b/kapitel16/systest.c new file mode 100644 index 0000000..2f368a1 --- /dev/null +++ b/kapitel16/systest.c @@ -0,0 +1,9 @@ +#include +#include + +int main(void) +{ + if (system("man ls") == -1) + fprintf(stderr, "Could not create child process\n"); + return 0; +} diff --git a/kapitel16/zombie.c b/kapitel16/zombie.c new file mode 100644 index 0000000..6d50d2c --- /dev/null +++ b/kapitel16/zombie.c @@ -0,0 +1,28 @@ +#define _XOPEN_SOURCE 500 +#include +#include +#include + +int main(void) +{ + pid_t pid; + pid = fork(); + if (pid == 0) + { + printf("Jag är barnprocessen och kommer bli en zombie\n"); + exit(0); + } + else if (pid > 0) + { + printf("Jag är föräldern och kommer att köras i " + "100 sekunder\n"); + sleep(100); + } + else + { + fprintf(stderr, "Något gick fel med fork()\n"); + return 1; + } + + return 0; +} diff --git a/kapitel17/daemon-ex2.c b/kapitel17/daemon-ex2.c new file mode 100644 index 0000000..9203041 --- /dev/null +++ b/kapitel17/daemon-ex2.c @@ -0,0 +1,108 @@ +#define _XOPEN_SOURCE 500 +#include +#include +#include +#include +#include +#include +#include + +void sigHandler(int sig); + +int main(void) +{ + pid_t process_id = 0; + pid_t sid = 0; + FILE *fp; + char pidfile[] = "/tmp/daemon-sig-ex.pid"; + /* Skapa barn/child process */ + process_id = fork(); + + /* Hantera eventuellt fel vid fork() */ + if (process_id < 0) + { + fprintf(stderr, "fork misslyckades!\n"); + exit(1); + } + /* Avsluta förälderprocessen */ + else if (process_id > 0) + { + exit(1); + } + + /* Starta en ny session */ + sid = setsid(); + if(sid < 0) + { + /* Avsluta ifall det inte gick att skapa en ny + session */ + fprintf(stderr, "Misslyckades att skapa en ny session\n"); + exit(1); + } + /* Gör en ny fork för att förhindra att demonen kan bli en + sessionsledare */ + process_id = fork(); + + /* Hantera eventuellt fel vid fork() */ + if (process_id < 0) + { + fprintf(stderr, "fork misslyckades!\n"); + exit(1); + } + /* Avsluta föräldern den eftersom allt arbete kommer att + utföras av demonen. Skriv också demonens PID-fil */ + else if (process_id > 0) + { + printf("Demonens PID: %d \n", process_id); + fp = fopen(pidfile, "w"); + fprintf(fp, "%d", process_id); + fclose(fp); + exit(0); + } + /* Sätt umask till 022 (rw-r--r-- / rwx-r-xr-x) */ + umask(022); + + /* Ändra aktuell katalog till / */ + chdir("/"); + + /* Stäng stdin, stdout och stderr och återöppna dem + till /dev/null */ + close(STDIN_FILENO); + close(STDOUT_FILENO); + close(STDERR_FILENO); + open("/dev/null", O_RDONLY); /* 0 = stdin */ + open("/dev/null", O_WRONLY); /* 1 = stdout */ + open("/dev/null", O_RDWR); /* 2 = stderr */ + + /* Registrera signalhanterarna, en för varje signal + som vi vill fånga upp */ + signal(SIGUSR1, sigHandler); + signal(SIGTERM, sigHandler); + /* Demonens arbete... */ + for(;;) + { + sleep(5); + } + return 0; +} + +void sigHandler(int sig) +{ + if (sig == SIGUSR1) + { + /* Skriv till syslog-demonen */ + syslog(LOG_DAEMON, "Tog emot SIGUSR1"); + } + else if (sig == SIGTERM) + { + /* Samma som ovan */ + syslog(LOG_DAEMON, "Tog emot SIGTERM"); + } + else + { + syslog(LOG_DAEMON, "Någonting hände med demonen..."); + } + /* Signalhanteraren återställs efter första signalen, + vi måste därför sätta den igen */ + signal(sig, sigHandler); +} diff --git a/kapitel17/daemon-sig-ex1.c b/kapitel17/daemon-sig-ex1.c new file mode 100644 index 0000000..9bb7994 --- /dev/null +++ b/kapitel17/daemon-sig-ex1.c @@ -0,0 +1,106 @@ +#define _XOPEN_SOURCE 500 +#include +#include +#include +#include +#include +#include +#include +void sigHandler(int sig); +int main(void) +{ + pid_t process_id = 0; + pid_t sid = 0; + FILE *fp; + char pidfile[] = "/tmp/daemon-sig-ex.pid"; + /* Skapa barn/child process */ + process_id = fork(); + + /* Hantera eventuellt fel vid fork() */ + if (process_id < 0) + { + fprintf(stderr, "fork misslyckades!\n"); + exit(1); + } + /* Avsluta förälderprocessen */ + else if (process_id > 0) + { + exit(1); + } + + /* Starta en ny session */ + sid = setsid(); + if(sid < 0) + { + /* Avsluta ifall det inte gick att skapa en ny + session */ + fprintf(stderr, "Misslyckades att skapa en ny session\n"); + exit(1); + } + /* Gör en ny fork för att förhindra att demonen kan bli en + sessionsledare */ + process_id = fork(); + + /* Hantera eventuellt fel vid fork() */ + if (process_id < 0) + { + fprintf(stderr, "fork misslyckades!\n"); + exit(1); + } + /* Avsluta föräldern den eftersom allt arbete kommer att + utföras av demonen. Skriv också demonens PID-fil */ + else if (process_id > 0) + { + printf("Demonens PID: %d \n", process_id); + fp = fopen(pidfile, "w"); + fprintf(fp, "%d", process_id); + fclose(fp); + exit(0); + } + /* Sätt umask till 022 (rw-r--r-- / rwx-r-xr-x) */ + umask(022); + + /* Ändra aktuell katalog till / */ + chdir("/"); + + /* Stäng stdin, stdout och stderr och återöppna dem + till /dev/null */ + close(STDIN_FILENO); + close(STDOUT_FILENO); + close(STDERR_FILENO); + open("/dev/null", O_RDONLY); /* 0 = stdin */ + open("/dev/null", O_WRONLY); /* 1 = stdout */ + open("/dev/null", O_RDWR); /* 2 = stderr */ + + /* Registrera signalhanterarna, en för varje signal + som vi vill fånga upp */ + signal(SIGUSR1, sigHandler); + signal(SIGTERM, sigHandler); + /* Demonens arbete... */ + for(;;) + { + sleep(5); + } + return 0; +} + +void sigHandler(int sig) +{ + if (sig == SIGUSR1) + { + /* Skriv till syslog-demonen */ + syslog(LOG_DAEMON, "Tog emot SIGUSR1"); + } + else if (sig == SIGTERM) + { + /* Samma som ovan */ + syslog(LOG_DAEMON, "Tog emot SIGTERM"); + } + else + { + syslog(LOG_DAEMON, "Någonting hände med demonen..."); + } + /* Signalhanteraren återställs efter första signalen, + vi måste därför sätta den igen */ + signal(sig, sigHandler); +} diff --git a/kapitel17/daemon-sig-ex2.c b/kapitel17/daemon-sig-ex2.c new file mode 100644 index 0000000..fb21313 --- /dev/null +++ b/kapitel17/daemon-sig-ex2.c @@ -0,0 +1,125 @@ +#define _XOPEN_SOURCE 500 +#include +#include +#include +#include +#include +#include +#include + +char pidfile[] = "/tmp/daemon-sig-ex.pid"; + +void sigHandler(int sig); +void shutDown(int sig); + +int main(void) +{ + pid_t process_id = 0; + pid_t sid = 0; + FILE *fp; + /* Skapa barn/child process */ + process_id = fork(); + + /* Hantera eventuellt fel vid fork() */ + if (process_id < 0) + { + fprintf(stderr, "fork misslyckades!\n"); + exit(1); + } + /* Avsluta förälderprocessen */ + else if (process_id > 0) + { + exit(1); + } + + /* Starta en ny session */ + sid = setsid(); + + if(sid < 0) + { + /* Avsluta ifall det inte gick att skapa en ny + session */ + fprintf(stderr, "Misslyckades att skapa en ny session\n"); + exit(1); + } + /* Gör en ny fork för att förhindra att demonen kan bli en + sessionsledare */ + process_id = fork(); + + /* Hantera eventuellt fel vid fork() */ + if (process_id < 0) + { + fprintf(stderr, "fork misslyckades!\n"); + exit(1); + } + /* Avsluta föräldern den eftersom allt arbete kommer att + utföras av demonen. Skriv också demonens PID-fil */ + else if (process_id > 0) + { + printf("Demonens PID: %d \n", process_id); + fp = fopen(pidfile, "w"); + fprintf(fp, "%d", process_id); + fclose(fp); + exit(0); + } + + /* Sätt umask till 022 (rw-r--r-- / rwx-r-xr-x) */ + umask(022); + + /* Ändra aktuell katalog till / */ + chdir("/"); + + /* Stäng stdin, stdout och stderr. Dessa behövs inte + i en demonprocess */ + close(STDIN_FILENO); + close(STDOUT_FILENO); + close(STDERR_FILENO); + open("/dev/null", O_RDONLY); /* 0 = stdin */ + open("/dev/null", O_WRONLY); /* 1 = stdout */ + open("/dev/null", O_RDWR); /* 2 = stderr */ + + /* Registrera signalhanterarna, en för varje signal + som vi vill fånga upp */ + signal(SIGUSR1, sigHandler); + signal(SIGTERM, sigHandler); + signal(SIGABRT, shutDown); + signal(SIGQUIT, shutDown); + signal(SIGINT, shutDown); + + /* Demonens arbete... */ + for(;;) + { + sleep(5); + } + return 0; +} + +void sigHandler(int sig) +{ + if (sig == SIGUSR1) + { + /* Skriv till syslog-demonen */ + syslog(LOG_DAEMON, "Tog emot SIGUSR1"); + } + else if (sig == SIGTERM) + { + /* Samma som ovan */ + syslog(LOG_DAEMON, "Tog emot SIGTERM"); + } + else + { + syslog(LOG_DAEMON, "Någonting hände med demonen..."); + } + /* Signalhanteraren återställs efter första signalen, + vi måste därför sätta den igen */ + signal(sig, sigHandler); +} + +void shutDown(int sig) +{ + syslog(LOG_DAEMON, "Demonen avslutas"); + /* Ta bort PID-filen */ + if ( unlink(pidfile) == -1 ) + syslog(LOG_DAEMON, "Kunde inte ta bort PID-filen"); + exit(0); +} diff --git a/kapitel17/fifo-client-ex1.c b/kapitel17/fifo-client-ex1.c new file mode 100644 index 0000000..9a526c5 --- /dev/null +++ b/kapitel17/fifo-client-ex1.c @@ -0,0 +1,20 @@ +#include +#include + +#define FIFONAM "/tmp/testfifo" + +int main(void) +{ + FILE *fp; + signed char c; + if ( access(FIFONAM, R_OK) != 0 ) + { + fprintf(stderr, "Problem att öppna %s\n", FIFONAM); + return 1; + } + fp = fopen(FIFONAM, "r"); + while ((c = getc(fp)) != EOF) + putchar(c); + fclose(fp); + return 0; +} diff --git a/kapitel17/fifo-ex1.c b/kapitel17/fifo-ex1.c new file mode 100644 index 0000000..5c2572a --- /dev/null +++ b/kapitel17/fifo-ex1.c @@ -0,0 +1,79 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#define FIFONAM "/tmp/testfifo" + +/* Skapa fifofd i det globala scopet så att + vi kan stänga den ifrån signalhanteraren. */ +int fifofd; + +void cleanUp(int signum); + +int main(void) +{ + char msg[] = "Ett meddelande till klienterna\n"; + + /* Registrera signalhanterare för vanliga "avsluts-signaler" */ + signal(SIGINT, cleanUp); + signal(SIGQUIT, cleanUp); + signal(SIGABRT, cleanUp); + signal(SIGTERM, cleanUp); + /* Ignorera SIGPIPE, annars avslutas programmet när + mottagaren stängs */ + signal(SIGPIPE, SIG_IGN); + + /* Skapa FIFOn. S_IWUSR och S_IRUSR är detsamma som för + open() och creat() */ + if ( mkfifo(FIFONAM, S_IWUSR | S_IRUSR) != 0) + { + if (errno == EEXIST) + { + fprintf(stderr, "FIFOn finns redan, använder den\n"); + } + else + { + perror("mkfifo"); + return 1; + } + } + + /* Öppna FIFOn */ + fifofd = open(FIFONAM, O_WRONLY); + if (fifofd < 0) + { + perror("open"); + return 1; + } + + /* Skriv meddelanden i en oändlig loop */ + while(1) + { + write(fifofd, msg, sizeof(msg)); + sleep(1); /* Vänta en sekund mellan varje körning */ + } + /* Hit bör vi aldrig komma, men fall i fall så städar vi upp */ + unlink(FIFONAM); + close(fifofd); + return 0; +} + +void cleanUp(int signum) +{ + /* Stäng fildeskriptorn */ + if ( close(fifofd) == -1 ) + perror("cleanUp - close"); + + /* Radera FIFO-filen från systemet & avsluta programmet */ + if ( unlink(FIFONAM) == -1 ) + { + perror("cleanUp - unlink"); + exit(1); + } + exit(0); +} diff --git a/kapitel17/my-msg-recv.c b/kapitel17/my-msg-recv.c new file mode 100644 index 0000000..9d8e9cd --- /dev/null +++ b/kapitel17/my-msg-recv.c @@ -0,0 +1,45 @@ +#define _XOPEN_SOURCE 500 +#include +#include +#include +#include +#include + +#define MAX 100 + +int main(void) +{ + /* Struktur som krävs av msgsnd & msgrcv */ + struct msgbuf + { + long mtype; + char mtext[MAX]; + }; + + int id; + key_t key = 12345; + struct msgbuf msg; + msg.mtext[0] = '\0'; + + /* Kalla msgget för att få ett ID-nummer till kön. + Observera att vi här utelämnar IPC_CREAT. */ + if ( (id = msgget(key, 0660)) < 0 ) + { + fprintf(stderr, "Could not open message queue\n"); + perror("msgget"); + return 1; + } + + /* Ta emot meddelandet och spara det i msg */ + if ( msgrcv(id, &msg, MAX, 1, 0) < 0 ) + { + fprintf(stderr, "Could not receive messages\n"); + perror("msgrcv"); + return 1; + } + + /* Skriv ut meddelandet */ + printf("%s\n", msg.mtext); + + return 0; +} diff --git a/kapitel17/my-msg-send.c b/kapitel17/my-msg-send.c new file mode 100644 index 0000000..dfeb4a2 --- /dev/null +++ b/kapitel17/my-msg-send.c @@ -0,0 +1,53 @@ +#define _XOPEN_SOURCE 500 +#include +#include +#include +#include +#include + +#define MAX 100 + +int main(void) +{ + /* Struktur som krävs av msgsnd & msgrcv */ + struct msgbuf + { + long mtype; + char mtext[MAX]; + }; + + /* Variabler vi behöver */ + int id; + key_t key = 12345; + struct msgbuf msg; + size_t msglen; + msg.mtext[0] = '\0'; + + /* Kalla msgget för att få ett ID-nummer till kön. + IPC_CREAT är flaggan för att skapa en kö. 0660 + är rättigheterna för kön */ + if ( (id = msgget(key, IPC_CREAT | 0660)) < 0 ) + { + fprintf(stderr, "Could not create message queue\n"); + perror("msgget"); + return 1; + } + + /* Komponera ett testmeddelande. mtype är till för att + identifiera just detta meddelandet i kön. mtext är + det faktiska innehållet och msglen är längden på + meddelandet */ + msg.mtype = 1; + strcat(msg.mtext, "Hejsan svejsan"); + msglen = strlen(msg.mtext) + 1; + + /* Skicka meddelandet */ + if ( msgsnd(id, &msg, msglen, IPC_NOWAIT) < 0 ) + { + fprintf(stderr, "Could not send message\n"); + perror("msgsend"); + return 1; + } + + return 0; +} diff --git a/kapitel17/pipes-ex1.c b/kapitel17/pipes-ex1.c new file mode 100644 index 0000000..e92f9ea --- /dev/null +++ b/kapitel17/pipes-ex1.c @@ -0,0 +1,27 @@ +#include +#include +#include +#define MAX 7 + +int main(void) +{ + int pipefd[2]; + pid_t pid; + char line[MAX]; + + pipe(pipefd); + pid = fork(); + + if (pid > 0) + { + close(pipefd[0]); + write(pipefd[1], "Hejsan", MAX); + } + else + { + close(pipefd[1]); + read(pipefd[0], line, MAX); + printf("%s\n", line); + } + return 0; +} diff --git a/kapitel17/sig-client.c b/kapitel17/sig-client.c new file mode 100644 index 0000000..057b17c --- /dev/null +++ b/kapitel17/sig-client.c @@ -0,0 +1,61 @@ +#define _XOPEN_SOURCE 500 +#include +#include +#include +#include + +void printUsage(char *arg); + +int main(int argc, char* argv[]) +{ + FILE *fp; + int opt; + pid_t process_id; + char pidfile[] = "/tmp/daemon-sig-ex.pid"; + + /* Kontrollera ifall PID-filen finns */ + if ( (fp = fopen(pidfile, "r")) == 0 ) + { + fprintf(stderr, "Ingen PID-fil, körs verkligen demonen?\n"); + return 1; + } + /* Läs in PID till process_id variabeln */ + fscanf(fp, "%d", &process_id); + + /* Om inga argument angavs, skriv ut demonens PID */ + if (argc == 1) + printf("Demonen körs med PID: %d\n", process_id); + + /* Behandla argument till programmet */ + while ((opt = getopt(argc, argv, "utqh")) != -1) + { + switch (opt) + { + case 'u': + kill(process_id, SIGUSR1); + break; + case 't': + kill(process_id, SIGTERM); + break; + case 'q': + kill(process_id, SIGQUIT); + break; + case 'h': + printUsage(argv[0]); + return 0; + default: + printUsage(argv[0]); + return 1; + } + } + return 0; +} + +void printUsage(char *arg) +{ + fprintf(stderr, "Usage: %s [-u] [-t] [-q] [-h]\n" + "-u = send SIGUSR1 to daemon\n" + "-t = send SIGTERM to daemon\n" + "-q = send SIGQUIT to quit the daemon\n" + "-h = display help\n", arg); +} diff --git a/kapitel17/unix-socket-client.c b/kapitel17/unix-socket-client.c new file mode 100644 index 0000000..1c2b049 --- /dev/null +++ b/kapitel17/unix-socket-client.c @@ -0,0 +1,48 @@ +#define _XOPEN_SOURCE 700 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define MAXLEN 32 + +int main(void) +{ + const char sockname[] = "/tmp/tidssocket"; + int fd; + struct sockaddr_un addr; + char recvbuffer[MAXLEN]; + + /* skapa en socket fildeskriptor */ + fd = socket(AF_UNIX, SOCK_STREAM, 0); + if ( fd == -1 ) + { + perror("Create socket failed"); + return 1; + } + /* sätt adressfamiljen och socket-filen */ + addr.sun_family = AF_UNIX; + strcpy(addr.sun_path, sockname); + + /* anslut till servern */ + if ( (connect(fd, (const struct sockaddr*) &addr, + sizeof(struct sockaddr_un))) == -1 ) + { + perror("Can't connect"); + fprintf(stderr, "The server is down?\n"); + return 1; + } + /* läs tiden från servern */ + if ( (read(fd, recvbuffer, MAXLEN)) == -1 ) + { + perror("Can't read"); + return 1; + } + printf("Server time is: %s", recvbuffer); + write(fd, "Thank you for the time", 23); + return 0; +} diff --git a/kapitel17/unix-socket-server.c b/kapitel17/unix-socket-server.c new file mode 100644 index 0000000..1ce30e2 --- /dev/null +++ b/kapitel17/unix-socket-server.c @@ -0,0 +1,87 @@ +#define _XOPEN_SOURCE 700 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define MAXLEN 32 + +void cleanUp(int signum); +const char sockname[] = "/tmp/tidssocket"; +int connfd; +int datafd; + +int main(void) +{ + struct sockaddr_un addr; + char buffer[MAXLEN]; + char recvbuffer[MAXLEN]; + time_t current_time; + struct tm *local_time; + + /* registrera signalhanterarna */ + signal(SIGTERM, cleanUp); + signal(SIGABRT, cleanUp); + signal(SIGQUIT, cleanUp); + signal(SIGINT, cleanUp); + + /* skapa en socket fildeskriptor */ + connfd = socket(AF_UNIX, SOCK_STREAM, 0); + if ( connfd == -1 ) + { + perror("Create socket failed"); + return 1; + } + /* sätt adressfamiljen till UNIX-socket */ + addr.sun_family = AF_UNIX; + strcpy(addr.sun_path, sockname); + /* knyt ihop namnet och adressen och casta + sockaddr_un till sockaddr) */ + if ( (bind(connfd, (const struct sockaddr*)&addr, + sizeof(struct sockaddr_un))) == -1 ) + { + perror("Binding socket failed"); + return 1; + } + /* lyssna efter anslutningar */ + if ( (listen(connfd, 20)) == -1 ) + { + perror("Listen error"); + return 1; + } + + /* acceptera anslutningen, skapa en ny data-fildeskriptor, + och skicka tiden till klienten */ + while(1) + { + datafd = accept(connfd, NULL, NULL); + if (datafd == -1 ) + { + perror("Accept error"); + return 1; + } + printf("Client connected, sending time\n"); + current_time = time(NULL); + local_time = localtime(¤t_time); + strcpy(buffer, asctime(local_time)); + write(datafd, buffer, MAXLEN); + read(datafd, recvbuffer, MAXLEN); + printf("Client respons: %s\n", recvbuffer); + close(datafd); /* stäng datafd efter varje anrop */ + } + return 0; /* fall i fall */ +} + +void cleanUp(int signum) +{ + printf("Quitting and cleaning up\n"); + close(datafd); + close(connfd); + unlink(sockname); + exit(0); +} diff --git a/kapitel18/mygetip.c b/kapitel18/mygetip.c new file mode 100644 index 0000000..abedd90 --- /dev/null +++ b/kapitel18/mygetip.c @@ -0,0 +1,61 @@ +#define _XOPEN_SOURCE 700 +#include +#include +#include +#include +#include +#include +#include +#include +#define MAXSIZE 100 + +int main(int argc, char *argv[]) +{ + struct addrinfo hints, *res, *result; + char addrstr[MAXSIZE]; + char host[MAXSIZE]; + void *ptr; + + /* argument till programmet */ + if (argc == 2) + { + strncpy(host, argv[1], MAXSIZE); + } + else + { + printf("Please specify a host to lookup\n"); + return 1; + } + + memset (&hints, 0, sizeof (hints)); /* nolla ut hints */ + hints.ai_family = AF_UNSPEC; /* både IPv4 och IPv6 */ + hints.ai_socktype = SOCK_STREAM; + + /* hämta IP */ + if ( getaddrinfo (host, NULL, &hints, &result) != 0 ) + { + perror ("getaddrinfo"); + return 1; + } + + res = result; + + while (res) /* loopa över alla IP-adresser */ + { + switch (res->ai_family) /* IPv4 eller IPv6 */ + { + case AF_INET: /* IPv4 */ + ptr = &((struct sockaddr_in *) res->ai_addr)->sin_addr; + break; + case AF_INET6: /* IPv6 */ + ptr = &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr; + break; + } + /* omvandla binär-IP till läslig IP-adress */ + inet_ntop (res->ai_family, ptr, addrstr, MAXSIZE); + printf ("%s\n", addrstr); + res = res->ai_next; /* nästa IP i listan */ + } + freeaddrinfo(result); /* frigör minnet */ + return 0; +} diff --git a/kapitel18/tcp-client.c b/kapitel18/tcp-client.c new file mode 100644 index 0000000..9ef397a --- /dev/null +++ b/kapitel18/tcp-client.c @@ -0,0 +1,91 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAXLINE 1024 +#define SIZE 20 +int sockfd; + +void cleanUp(int signum); + +int main(int argc, char* argv[]) +{ + char ipaddr[SIZE] = "127.0.0.1"; + int port = 9000; + char buffer[MAXLINE]; + char message[MAXLINE]; + struct sockaddr_in servaddr; + int n; + socklen_t len; + + /* skapa socket-filen */ + if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) + { + perror("socket creation failed"); + return 1; + } + + /* kontrollera om vi angav en adress */ + if (argc == 2) + { + strncpy(ipaddr, argv[1], SIZE-1); + } + + /* registrera signalhanterarna */ + signal(SIGTERM, cleanUp); + signal(SIGABRT, cleanUp); + signal(SIGQUIT, cleanUp); + signal(SIGINT, cleanUp); + signal(SIGPIPE, cleanUp); + + /* nolla ut strukturen med adressen */ + memset(&servaddr, 0, sizeof(servaddr)); + + /* information om IP-adress och port */ + servaddr.sin_family = AF_INET; /* IPv4 */ + servaddr.sin_port = htons(port); + servaddr.sin_addr.s_addr = inet_addr(ipaddr);; + + len = sizeof(servaddr); /* storleken på adressen */ + + if (connect(sockfd, (struct sockaddr *)&servaddr, len) != 0) + { + perror("connect"); + return 1; + } + else + { + printf("Connected to the server..\n"); + } + + /* läs meddelanden och skicka till servern */ + while(1) + { + printf("Type your message: "); + fgets(message, sizeof(message), stdin); + /* byt ut radbrytningstecknet mot null */ + message[strcspn(message, "\n")] = '\0'; + /* skicka meddelandandet till servern med 'sendto' */ + write(sockfd, message, sizeof(message)); + /* ta emot meddelande från servern med 'recvfrom' */ + n = read(sockfd, buffer, sizeof(buffer)); + buffer[n] = '\0'; /* avsluta strängen med null */ + /* skriv ut svaret från servern */ + printf("Server: %s\n", buffer); + } + close(sockfd); + return 0; +} + +void cleanUp(int signum) +{ + printf("\nQuitting gracefully and closing the socket\n"); + close(sockfd); + exit(0); +} diff --git a/kapitel18/tcp-server.c b/kapitel18/tcp-server.c new file mode 100644 index 0000000..1dce5e2 --- /dev/null +++ b/kapitel18/tcp-server.c @@ -0,0 +1,113 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAXLINE 1024 +#define SIZE 20 +int sockfd; +int datafd; + +void cleanUp(int signum); + +int main(int argc, char* argv[]) +{ + char ipaddr[SIZE] = "127.0.0.1"; + int port = 9000; + char buffer[MAXLINE]; + char *confirmation = "Message received"; + struct sockaddr_in servaddr, cliaddr; + int n; + socklen_t len; + + /* skapa socket */ + if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) + { + perror("socket creation failed"); + return 1; + } + + /* kontrollera om vi angav en lyssnar-adress */ + if (argc == 2) + { + strncpy(ipaddr, argv[1], SIZE-1); + } + + /* registrera signalhanterarna */ + signal(SIGTERM, cleanUp); + signal(SIGABRT, cleanUp); + signal(SIGQUIT, cleanUp); + signal(SIGINT, cleanUp); + signal(SIGPIPE, cleanUp); /* när klienten kopplar från servern + får den en SIGPIPE */ + + /* nolla adress-strukturerna innan vi använder dem */ + memset(&servaddr, 0, sizeof(servaddr)); + memset(&cliaddr, 0, sizeof(cliaddr)); + + /* information om IP-adress och port */ + servaddr.sin_family = AF_INET; /* IPv4 */ + servaddr.sin_addr.s_addr = inet_addr(ipaddr); + servaddr.sin_port = htons(port); + + /* knyt ihop vår socket med adressen */ + if ( bind(sockfd, (const struct sockaddr *)&servaddr, + sizeof(servaddr)) < 0 ) + { + perror("bind"); + return 1; + } + + /* lyssna efter inkommande anslutningar */ + if ( (listen(sockfd, 5)) != 0 ) + { + perror("listen"); + return 1; + } + else + { + printf("Server listening...\n"); + } + len = sizeof(cliaddr); /* storleken på adressen */ + + /* acceptera inkommande anslutning */ + datafd = accept(sockfd, (struct sockaddr *)&cliaddr, &len); + if (datafd < 0) + { + perror("accept"); + return 1; + } + else + { + printf("Server accepted connection...\n"); + } + + /* ta emot paket och loopa tills klienten kopplar från */ + while(1) + { + n = read(datafd, buffer, sizeof(buffer)); + /* skriv ut meddelandet vi tog emot från klienten och + skicka en bekräftelse */ + buffer[n] = '\0'; /* avsluta strängen med null */ + printf("Client: %s\n", buffer); + write(datafd, confirmation, strlen(confirmation)+1); + printf("Confirmation message sent to client\n"); + } + /* vi når aldrig hit - men fall i fall */ + close(sockfd); + close(datafd); + return 0; +} + +void cleanUp(int signum) +{ + printf("Quitting gracefully and closing the socket\n"); + close(sockfd); + close(datafd); + exit(0); +} diff --git a/kapitel18/udp-client.c b/kapitel18/udp-client.c new file mode 100644 index 0000000..3dcfa05 --- /dev/null +++ b/kapitel18/udp-client.c @@ -0,0 +1,85 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAXLINE 1024 +#define SIZE 20 +int sockfd; + +void cleanUp(int signum); + +int main(int argc, char* argv[]) +{ + char ipaddr[SIZE] = "127.0.0.1"; + int port = 9000; + char buffer[MAXLINE]; + char message[MAXLINE]; + struct sockaddr_in servaddr; + int n; + socklen_t len; + + /* skapa socket-filen */ + if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) + { + perror("socket creation failed"); + return 1; + } + + /* kontrollera om vi angav en adress */ + if (argc == 2) + { + strncpy(ipaddr, argv[1], SIZE-1); + } + + /* registrera signalhanterarna */ + signal(SIGTERM, cleanUp); + signal(SIGABRT, cleanUp); + signal(SIGQUIT, cleanUp); + signal(SIGINT, cleanUp); + + /* nolla ut strukturen med adressen */ + memset(&servaddr, 0, sizeof(servaddr)); + + /* information om IP-adress och port */ + servaddr.sin_family = AF_INET; /* IPv4 */ + servaddr.sin_port = htons(port); + servaddr.sin_addr.s_addr = inet_addr(ipaddr);; + + len = sizeof(servaddr); /* storleken på adressen */ + + /* läs meddelanden och skicka till servern */ + while(1) + { + printf("Type your message: "); + fgets(message, sizeof(message), stdin); + /* byt ut radbrytningstecknet mot null */ + message[strcspn(message, "\n")] = '\0'; + /* skicka meddelandandet till servern med 'sendto' */ + sendto(sockfd, (const char *)message, strlen(message), + 0, (const struct sockaddr *) &servaddr, len); + + /* ta emot meddelande från servern med 'recvfrom' */ + n = recvfrom(sockfd, (char *)buffer, MAXLINE, + MSG_WAITALL, (struct sockaddr *) &servaddr, &len); + buffer[n] = '\0'; /* avsluta strängen med null */ + + /* skriv ut svaret från servern */ + printf("Server: %s\n", buffer); + } + /* vi når aldrig hit - men fall i fall */ + close(sockfd); + return 0; +} + +void cleanUp(int signum) +{ + printf("\nQuitting gracefully and closing the socket\n"); + close(sockfd); + exit(0); +} diff --git a/kapitel18/udp-server.c b/kapitel18/udp-server.c new file mode 100644 index 0000000..d82b0a5 --- /dev/null +++ b/kapitel18/udp-server.c @@ -0,0 +1,90 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAXLINE 1024 +#define SIZE 20 +int sockfd; + +void cleanUp(int signum); + +int main(int argc, char* argv[]) +{ + char ipaddr[SIZE] = "127.0.0.1"; + int port = 9000; + char buffer[MAXLINE]; + char *confirmation = "Message received"; + struct sockaddr_in servaddr, cliaddr; + int n; + socklen_t len; + + /* skapa socket */ + if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) + { + perror("socket creation failed"); + return 1; + } + + /* kontrollera om vi angav en lyssnar-adress */ + if (argc == 2) + { + strncpy(ipaddr, argv[1], SIZE-1); + } + + /* registrera signalhanterarna */ + signal(SIGTERM, cleanUp); + signal(SIGABRT, cleanUp); + signal(SIGQUIT, cleanUp); + signal(SIGINT, cleanUp); + + /* nolla adress-strukturerna innan vi använder dem */ + memset(&servaddr, 0, sizeof(servaddr)); + memset(&cliaddr, 0, sizeof(cliaddr)); + + /* information om IP-adress och port */ + servaddr.sin_family = AF_INET; /* IPv4 */ + servaddr.sin_addr.s_addr = inet_addr(ipaddr); + servaddr.sin_port = htons(port); + + /* knyt ihop vår socket med adressen */ + if ( bind(sockfd, (const struct sockaddr *)&servaddr, + sizeof(servaddr)) < 0 ) + { + perror("bind failed"); + return 1; + } + len = sizeof(cliaddr); /* storleken på adressen */ + + /* ta emot udp-paket och loopa för evigt */ + while(1) + { + n = recvfrom(sockfd, (char *)buffer, MAXLINE, + MSG_WAITALL, ( struct sockaddr *) &cliaddr, + &len); + buffer[n] = '\0'; /* avsluta strängen med null */ + + /* skriv ut meddelandet vi tog emot från klienten och skicka en + bekräftelse */ + printf("Client: %s\n", buffer); + sendto(sockfd, (const char *)confirmation, + strlen(confirmation), 0, + (const struct sockaddr *) &cliaddr, len); + printf("Confirmation message sent to client\n"); + } + /* vi når aldrig hit - men fall i fall */ + close(sockfd); + return 0; +} + +void cleanUp(int signum) +{ + printf("Quitting gracefully and closing the socket\n"); + close(sockfd); + exit(0); +} diff --git a/kapitel19/felsok-ex1.c b/kapitel19/felsok-ex1.c new file mode 100644 index 0000000..7ce3ab8 --- /dev/null +++ b/kapitel19/felsok-ex1.c @@ -0,0 +1,17 @@ +#include + +int main(void) +{ + int x; + int y = 5; + + char text[20] = "Hejsan"; + + for (x = 1; y < 100; x++) + { + y = (y*3)-x; + } + printf("%s\n", text); + + return 0; +} diff --git a/kapitel19/felsok-ex2.c b/kapitel19/felsok-ex2.c new file mode 100644 index 0000000..99f199a --- /dev/null +++ b/kapitel19/felsok-ex2.c @@ -0,0 +1,25 @@ +#include +#include + +float circum(float d); + +int main(int argc, char *argv[]) +{ + float di; + if (argc < 2) + { + fprintf(stderr, "Usage: %s diamater\n", argv[0]); + return 1; + } + + di = atof(argv[1]); + printf ("Circumference of a circle with a diamater %.2f is" + " %.2f\n", di, circum(di)); + return 0; +} + +float circum(float d) +{ + float pi = 3.14159265; + return (pi*d); +} diff --git a/kapitel19/flt-fel1.c b/kapitel19/flt-fel1.c new file mode 100644 index 0000000..af487d7 --- /dev/null +++ b/kapitel19/flt-fel1.c @@ -0,0 +1,23 @@ +#include +#include +#include + +char *say(char namn[]); + +int main(void) +{ + char *mening = say("Jack-Benny"); + printf("%s\n", mening); + free(mening); + printf("Lisa hojtar: %s\n", mening); + return 0; +} + +char *say(char namn[]) +{ + char *str; + str = calloc(50, sizeof(char)); + strncat(str, "Hej ", 4); + strncat(str, namn, 45); + return str; +} diff --git a/kapitel19/leak1.c b/kapitel19/leak1.c new file mode 100644 index 0000000..2c1b2ab --- /dev/null +++ b/kapitel19/leak1.c @@ -0,0 +1,14 @@ +#include +#include +#include + +int main(void) +{ + char* buffer; + buffer = malloc(sizeof(char)*15); + *buffer = '\0'; + strcpy(buffer, "Hejsan svejsan"); + printf("%s\n", buffer); + free(buffer); + return 0; +} diff --git a/kapitel19/oinitialiserat-ex1.c b/kapitel19/oinitialiserat-ex1.c new file mode 100644 index 0000000..517d716 --- /dev/null +++ b/kapitel19/oinitialiserat-ex1.c @@ -0,0 +1,11 @@ +#include +#include +#include + +int main(void) +{ + char* str; + strcat(str, "Hej alla"); + printf("%s\n", str); + return 0; +} diff --git a/kapitel19/undersoka-minne.c b/kapitel19/undersoka-minne.c new file mode 100644 index 0000000..f575d63 --- /dev/null +++ b/kapitel19/undersoka-minne.c @@ -0,0 +1,17 @@ +#include +#include +#include + +int main(void) +{ + char *a; + a = malloc(10*sizeof(char)); + *a = '\0'; + strcpy(a, "Hej hej"); + printf("Strängen %s\n", a); + *a = '\0'; + printf("Strängen %s\n", a); + + free(a); + return 0; +} diff --git a/kapitel4/helloworld.c b/kapitel4/helloworld.c new file mode 100644 index 0000000..4a42a83 --- /dev/null +++ b/kapitel4/helloworld.c @@ -0,0 +1,7 @@ +#include + +int main(void) +{ + printf("Hello world!\n"); + return 0; +} diff --git a/kapitel4/namn.c b/kapitel4/namn.c new file mode 100644 index 0000000..3449956 --- /dev/null +++ b/kapitel4/namn.c @@ -0,0 +1,10 @@ +#include + +int main(void) +{ + char namn[12]; + printf("Vad heter du? "); + scanf("%11s", namn); + printf("Hej %s, nu ska vi lära oss C!\n", namn); + return 0; +} diff --git a/kapitel4/namn_unsafe.c b/kapitel4/namn_unsafe.c new file mode 100644 index 0000000..2c27b1b --- /dev/null +++ b/kapitel4/namn_unsafe.c @@ -0,0 +1,10 @@ +#include + +int main(void) +{ + char namn[12]; + printf("Vad heter du? "); + scanf("%s", namn); + printf("Hej %s, nu ska vi lära oss C!\n", namn); + return 0; +} diff --git a/kapitel4/namn_v2.c b/kapitel4/namn_v2.c new file mode 100644 index 0000000..5b5d8e4 --- /dev/null +++ b/kapitel4/namn_v2.c @@ -0,0 +1,10 @@ +#include + +int main(void) +{ + char namn[12]; + printf("Vad heter du? "); + fgets(namn, sizeof(namn), stdin); + printf("Hej %s, nu ska vi lära oss C!\n", namn); + return 0; +} diff --git a/kapitel4/namn_v3.c b/kapitel4/namn_v3.c new file mode 100644 index 0000000..13edb88 --- /dev/null +++ b/kapitel4/namn_v3.c @@ -0,0 +1,13 @@ +#include +#include + +int main(void) +{ + char namn[12]; + printf("Vad heter du? "); + fgets(namn, sizeof(namn), stdin); + /* byt ut \n mot \0 på namn[index] */ + namn[strcspn(namn, "\n")] = '\0'; + printf("Hej %s, nu ska vi lära oss C!\n", namn); + return 0; +} diff --git a/kapitel4/testa-strcspn.c b/kapitel4/testa-strcspn.c new file mode 100644 index 0000000..365a133 --- /dev/null +++ b/kapitel4/testa-strcspn.c @@ -0,0 +1,11 @@ +#include +#include + +int main(void) +{ + int len; + char namn[6] = "Kalle"; + len = strcspn(namn, "e"); + printf("%d\n", len); + return 0; +} diff --git a/kapitel5/agg.c b/kapitel5/agg.c new file mode 100644 index 0000000..2314081 --- /dev/null +++ b/kapitel5/agg.c @@ -0,0 +1,9 @@ +#include + +int main(void) +{ + enum mangd { par = 2, dussin = 12, tjog = 20, + skock = 60 }; + printf("Kalle beställer %d ägg\n", dussin); + return 0; +} diff --git a/kapitel5/aritmetik-cast1.c b/kapitel5/aritmetik-cast1.c new file mode 100644 index 0000000..b93cc03 --- /dev/null +++ b/kapitel5/aritmetik-cast1.c @@ -0,0 +1,8 @@ +#include + +int main(void) +{ + printf("9 / 2 = %d\n", 9/2); + printf("9 / 2 = %f\n", (float)9/2); + return 0; +} diff --git a/kapitel5/aritmetik-cast2.c b/kapitel5/aritmetik-cast2.c new file mode 100644 index 0000000..7fc34dc --- /dev/null +++ b/kapitel5/aritmetik-cast2.c @@ -0,0 +1,9 @@ +#include + +int main(void) +{ + int x = 50; + int y = 9; + printf("%d / %d = %f\n", x, y, x/(float)y); + return 0; +} diff --git a/kapitel5/aritmetik1.c b/kapitel5/aritmetik1.c new file mode 100644 index 0000000..56c9c8d --- /dev/null +++ b/kapitel5/aritmetik1.c @@ -0,0 +1,20 @@ +#include + +int main(void) +{ + int a = 5; + float b = 7.5; + int c; + + printf("Heltalet: %d\n", a); + printf("Flyttalet: %f\n", b); + + /* Aritmetik med heltal och flyttal */ + printf("%d + %f = %f\n", a, b, (a+b)); + + /* Se upp, här skalas decimaltecknet bort! */ + c = (a+b); + printf("%d + %f = %d\n", a, b, c); + + return 0; +} diff --git a/kapitel5/aritmetik2.c b/kapitel5/aritmetik2.c new file mode 100644 index 0000000..8f203a1 --- /dev/null +++ b/kapitel5/aritmetik2.c @@ -0,0 +1,8 @@ +#include + +int main(void) +{ + printf("9 / 2 = %d\n", 9/2); + printf("9 / 2 = %f\n", 9.0/2); + return 0; +} diff --git a/kapitel5/bytes.c b/kapitel5/bytes.c new file mode 100644 index 0000000..fb9c653 --- /dev/null +++ b/kapitel5/bytes.c @@ -0,0 +1,10 @@ +#include + +int main(void) +{ + printf("En char: %lu byte\n", sizeof(char)); + printf("En vanlig int: %lu byte\n", sizeof(int)); + printf("En long int: %lu byte\n", sizeof(long int)); + printf("En short int: %lu byte\n", sizeof(short int)); + return 0; +} diff --git a/kapitel5/bytes_cast.c b/kapitel5/bytes_cast.c new file mode 100644 index 0000000..da2903b --- /dev/null +++ b/kapitel5/bytes_cast.c @@ -0,0 +1,14 @@ +#include + +int main(void) +{ + printf("En char: %lu byte\n", + (unsigned long int)sizeof(char)); + printf("En vanlig int: %lu byte\n", + (unsigned long int)sizeof(int)); + printf("En long int: %lu byte\n", + (unsigned long int)sizeof(long int)); + printf("En short int: %lu byte\n", + (unsigned long int)sizeof(short int)); + return 0; +} diff --git a/kapitel5/bytes_zu.c b/kapitel5/bytes_zu.c new file mode 100644 index 0000000..ceea8d6 --- /dev/null +++ b/kapitel5/bytes_zu.c @@ -0,0 +1,10 @@ +#include + +int main(void) +{ + printf("En char: %zu byte\n", sizeof(char)); + printf("En vanlig int: %zu byte\n", sizeof(int)); + printf("En long int: %zu byte\n", sizeof(long int)); + printf("En short int: %zu byte\n", sizeof(short int)); + return 0; +} diff --git a/kapitel5/casting-ex1.c b/kapitel5/casting-ex1.c new file mode 100644 index 0000000..d5f585b --- /dev/null +++ b/kapitel5/casting-ex1.c @@ -0,0 +1,22 @@ +#include + +int main(void) +{ + char c = 'A'; + float x = 3.14; + float y = 3.999; + int z = 45; + long int lx = 922337203685477580; + long int ly = 345; + int ii = 429496729; + + printf("Casta float %f till int: %d\n", x, (int)x); + printf("Casta float %f till int: %d\n", y, (int)y); + printf("Casta int %d till float: %f\n", z, (float)z); + printf("Casta char %c till int: %d\n", c, (int)c); + printf("Casta long int %li till int: %d\n", lx, (int)lx); + printf("Casta long int %li till int: %d\n", ly, (int)ly); + printf("Casta int %d till short int: %d\n", ii, (short int)ii); + + return 0; +} diff --git a/kapitel5/charint.c b/kapitel5/charint.c new file mode 100644 index 0000000..8670b7d --- /dev/null +++ b/kapitel5/charint.c @@ -0,0 +1,14 @@ +#include + +int main(void) +{ + char tecken = 'A'; + int x = 66; + int annat_tecken = 'C'; + + printf("%c = %d\n", tecken, tecken); + printf("%c = %d\n", x, x); + printf("%c = %d\n", annat_tecken, annat_tecken); + + return 0; +} diff --git a/kapitel5/const-int.c b/kapitel5/const-int.c new file mode 100644 index 0000000..cc77c5c --- /dev/null +++ b/kapitel5/const-int.c @@ -0,0 +1,9 @@ +#include + +int main(void) +{ + const int a = 10; + a = 15; + printf("a = %d\n", a); + return 0; +} diff --git a/kapitel5/flt.c b/kapitel5/flt.c new file mode 100644 index 0000000..c2aa030 --- /dev/null +++ b/kapitel5/flt.c @@ -0,0 +1,9 @@ +#include +#include + +int main(void) +{ + printf("Minsta möjliga float: %e\n", FLT_MIN); + printf("Största möjliga float: %e\n", FLT_MAX); + return 0; +} diff --git a/kapitel5/fmodtest.c b/kapitel5/fmodtest.c new file mode 100644 index 0000000..30af8ef --- /dev/null +++ b/kapitel5/fmodtest.c @@ -0,0 +1,11 @@ +#include +#include + +int main(void) +{ + float taljare = 19.5; + float namnare = 4.3; + printf("fmod(%0.1f, %0.1f) = %0.1f\n", taljare, namnare, + fmod(taljare,namnare)); + return 0; +} diff --git a/kapitel5/if-else-ex1.c b/kapitel5/if-else-ex1.c new file mode 100644 index 0000000..c98d0dd --- /dev/null +++ b/kapitel5/if-else-ex1.c @@ -0,0 +1,27 @@ +#include + +int main(void) +{ + int a = 5; + int b = 10; + + if (a < b) + { + printf ("%d är mindre än %d\n", a, b); + printf ("Uttrycket (%d < %d) ger talet: %d\n", a, b, (a + +int main(void) +{ + int a[8] = {1, 56, 39, 12, 9}; + printf("Objekt 0 = %d\n", a[0]); + printf("Objekt 1 = %d\n", a[1]); + printf("Objekt 2 = %d\n", a[2]); + printf("Objekt 3 = %d\n", a[3]); + printf("Objekt 4 = %d\n", a[4]); + printf("Objekt 5 = %d\n", a[5]); + printf("Objekt 6 = %d\n", a[6]); + printf("Objekt 7 = %d\n", a[7]); + return 0; +} diff --git a/kapitel5/konstant-tal.c b/kapitel5/konstant-tal.c new file mode 100644 index 0000000..b2dd442 --- /dev/null +++ b/kapitel5/konstant-tal.c @@ -0,0 +1,10 @@ +#include + +#define TAL 5 + +int main(void) +{ + #define TAL 1 + printf("Talet är: %d\n", TAL); + return 0; +} diff --git a/kapitel5/konstanter.c b/kapitel5/konstanter.c new file mode 100644 index 0000000..217af51 --- /dev/null +++ b/kapitel5/konstanter.c @@ -0,0 +1,11 @@ +#include +#define ETT_TAL 15 + +int main(void) +{ + const int annat_tal = 25; + printf ("%d\n", ETT_TAL); + printf ("%d\n", annat_tal); + + return 0; +} diff --git a/kapitel5/lager_v1.c b/kapitel5/lager_v1.c new file mode 100644 index 0000000..2542bd1 --- /dev/null +++ b/kapitel5/lager_v1.c @@ -0,0 +1,24 @@ +#include +#include + +int main(void) +{ + struct artikel + { + char namn[50]; + int antal; + float pris; + }; + + struct artikel lager; + + strcpy(lager.namn, "Skruv"); + lager.antal = 12; + lager.pris = 1.5; + + printf("Följande artiklar finns i lager\n\n"); + printf("Namn: %s\tAntal på lager: %d\tPris: %.2f\n", + lager.namn, lager.antal, lager.pris); + + return 0; +} diff --git a/kapitel5/lager_v2.c b/kapitel5/lager_v2.c new file mode 100644 index 0000000..e69f8fc --- /dev/null +++ b/kapitel5/lager_v2.c @@ -0,0 +1,38 @@ +#include +#include +#define ARTIKLAR 3 + +int main(void) +{ + struct artikel + { + char namn[50]; + int antal; + float pris; + }; + + struct artikel lager[ARTIKLAR]; + int i; + + strcpy(lager[0].namn, "Skruv"); + lager[0].antal = 12; + lager[0].pris = 1.5; + + strcpy(lager[1].namn, "Hammare"); + lager[1].antal = 2; + lager[1].pris = 159; + + strcpy(lager[2].namn, "Skruvmejsel"); + lager[2].antal = 5; + lager[2].pris = 79.90; + + printf("Följande artiklar finns i lager\n"); + printf("-------------------------------\n\n"); + for (i = 0; i +#include +#define ARTIKLAR 3 + +int main(void) +{ + typedef struct artikel + { + char namn[50]; + int antal; + float pris; + }ART; + + ART lager[ARTIKLAR]; + int i; + + strcpy(lager[0].namn, "Skruv"); + lager[0].antal = 12; + lager[0].pris = 1.5; + + strcpy(lager[1].namn, "Hammare"); + lager[1].antal = 2; + lager[1].pris = 159; + + strcpy(lager[2].namn, "Skruvmejsel"); + lager[2].antal = 5; + lager[2].pris = 79.90; + + printf("Följande artiklar finns i lager\n"); + printf("-------------------------------\n\n"); + for (i = 0; i + +int main(void) +{ + printf("%d\n", 7+8*3); + printf("%d\n", (7+8)*3); + + return 0; +} diff --git a/kapitel5/max_int.c b/kapitel5/max_int.c new file mode 100644 index 0000000..70454d8 --- /dev/null +++ b/kapitel5/max_int.c @@ -0,0 +1,9 @@ +#include +#include + +int main(void) +{ + printf("Maximal signed int: %d\n", INT_MAX); + printf("Maximal unsigned int: %u\n", UINT_MAX); + return 0; +} diff --git a/kapitel5/modulo-ex1.c b/kapitel5/modulo-ex1.c new file mode 100644 index 0000000..c339d0e --- /dev/null +++ b/kapitel5/modulo-ex1.c @@ -0,0 +1,12 @@ +#include + +int main(void) +{ + printf("%d / %d = %d\n", 3, 2, 3/2); + printf("%d %% %d = %d\n\n", 3, 2, 3%2); + + printf("%d / %d = %d\n", 13, 4, 13/4); + printf("%d %% %d = %d\n", 13, 4, 13%4); + + return 0; +} diff --git a/kapitel5/struct-test.c b/kapitel5/struct-test.c new file mode 100644 index 0000000..7750a46 --- /dev/null +++ b/kapitel5/struct-test.c @@ -0,0 +1,28 @@ +#include + +int main(void) +{ + struct test1 + { + short int a; /* 2 bytes */ + /* 2 bytes utfyllnad (2+2=4) */ + int b; /* 4 bytes (4) */ + char c; /* 1 byte */ + char d; /* 1 byte */ + /* 2 bytes utfyllnad (1+1+2=4) */ + }; + + struct test2 + { + int b; /* 4 bytes (4) */ + char c; /* 1 bytes */ + char d; /* 1 bytes */ + short int a; /* 2 bytes (1+1+2=4) */ + }; + + printf("Storleken av test1: %lu bytes\n", + (long unsigned int)sizeof(struct test1)); + printf("Storleken av test2: %lu bytes\n", + (long unsigned int)sizeof(struct test2)); + return 0; +} diff --git a/kapitel5/type-demo.c b/kapitel5/type-demo.c new file mode 100644 index 0000000..409d81b --- /dev/null +++ b/kapitel5/type-demo.c @@ -0,0 +1,27 @@ +#include +#include + +int main(void) +{ + typedef char text[50]; /* Nytt alias 'text' för char[50] */ + typedef char tiny; /* Nytt alias 'tiny' för char */ + + text namn; + text adress; + text ort = "Ankeborg"; + tiny knattarna = 3; + + printf("Vad heter du? "); + fgets(namn, sizeof(text), stdin); + printf("Vilken gatuadress bor du på? "); + fgets(adress, sizeof(text), stdin); + namn[strcspn(namn, "\n")] = '\0'; + adress[strcspn(adress, "\n")] = '\0'; + + printf("En 'text' är %lu tecken stor.\n", + (unsigned long int)sizeof(text)); + printf("Hej %s, från %s %s.\n", namn, adress, ort); + printf("Knattarna är %d st.\n", knattarna); + + return 0; +} diff --git a/kapitel5/uniontest.c b/kapitel5/uniontest.c new file mode 100644 index 0000000..f4bad96 --- /dev/null +++ b/kapitel5/uniontest.c @@ -0,0 +1,23 @@ +#include +#include +int main(void) +{ + union myUnion /* Samma syntax som för struct */ + { + int x; + float y; + char z[20]; + } unionTest; /* Skapar en variabel unionTest ur myUnion */ + + printf("Storleken är %lu bytes\n", + (unsigned long int)sizeof(unionTest)); + + /* Endast unionTest.z nedan kommer innehålla ett riktigt värde */ + unionTest.x = 500; + unionTest.y = 3.14; + strcpy(unionTest.z, "Hej hopp!"); + printf("x = %d\ny = %f\nz = %s\n", unionTest.x, unionTest.y, + unionTest.z); + + return 0; +} diff --git a/kapitel5/uniontest_v2.c b/kapitel5/uniontest_v2.c new file mode 100644 index 0000000..60b7fc4 --- /dev/null +++ b/kapitel5/uniontest_v2.c @@ -0,0 +1,25 @@ +#include +#include + +int main(void) +{ + union myUnion /* Samma syntax som för struct */ + { + int x; + float y; + char z[20]; + } unionTest; /* Skapar en variabel unionTest ur myUnion */ + + printf("Storleken är %lu bytes\n", + (long unsigned int)sizeof(unionTest)); + + /* Här arbetar vi med en medlem i taget, helt korrekt */ + unionTest.x = 500; + printf("x = %d\n", unionTest.x); + unionTest.y = 3.14; + printf("y = %f\n", unionTest.y); + strcpy(unionTest.z, "Hej hopp!"); + printf("z = %s\n", unionTest.z); + + return 0; +} diff --git a/kapitel5/unsignedtest.c b/kapitel5/unsignedtest.c new file mode 100644 index 0000000..607cc9b --- /dev/null +++ b/kapitel5/unsignedtest.c @@ -0,0 +1,13 @@ +#include +#include + +int main(void) +{ + unsigned int i; + for (i = 10; i >= 0; i--) + { + printf("%u\n", i); + sleep(1); + } + return 0; +} diff --git a/kapitel5/veckodagar.c b/kapitel5/veckodagar.c new file mode 100644 index 0000000..1a1b398 --- /dev/null +++ b/kapitel5/veckodagar.c @@ -0,0 +1,20 @@ +#include + +int main(void) +{ + int idag; + enum veckodag { mandag = 1, tisdag, onsdag, + torsdag, fredag, lordag, sondag }; + idag = onsdag; + + if ( idag == lordag || idag == sondag ) + { + printf("Idag är det helg\n"); + } + else + { + printf("Idag är det vardag\n"); + } + + return 0; +} diff --git a/kapitel6/break-ex1.c b/kapitel6/break-ex1.c new file mode 100644 index 0000000..f737382 --- /dev/null +++ b/kapitel6/break-ex1.c @@ -0,0 +1,15 @@ +#include + +int main(void) +{ + int i; + + for(i=10; i>0; i--) + { + printf("i = %d\n", i); + if (i==4) + break; + } + + return 0; +} diff --git a/kapitel6/break-ex2.c b/kapitel6/break-ex2.c new file mode 100644 index 0000000..ced77cc --- /dev/null +++ b/kapitel6/break-ex2.c @@ -0,0 +1,21 @@ +#include + +int main(void) +{ + int i; + int j; + + for(i=10; i>0; i--) + { + printf("i = %d\n", i); + for (j=30; j<=40; j++) + { + printf("j = %d\n", j); + if (j==33) + { + break; + } + } + } + return 0; +} diff --git a/kapitel6/break-ex3.c b/kapitel6/break-ex3.c new file mode 100644 index 0000000..4761402 --- /dev/null +++ b/kapitel6/break-ex3.c @@ -0,0 +1,14 @@ +#include + +int main(void) +{ + int i = 10; + while (i>0) + { + printf ("i = %d\n", i); + if (i == 6) + break; + i--; + } + return 0; +} diff --git a/kapitel6/c99-for-loop.c b/kapitel6/c99-for-loop.c new file mode 100644 index 0000000..c1ad736 --- /dev/null +++ b/kapitel6/c99-for-loop.c @@ -0,0 +1,20 @@ +#include + +int main(void) +{ + for (int i=0; i<=10; i++) + printf("i = %d\n", i); + + /* Nedanstående printf()-rad fungerar inte eftersom i är lokal + för for-loopen ovan. Testa genom att av-kommentera raden */ + /* printf("Utanför loopen är i = %d\n", i); */ + + int j; + for (j=10; j>=0; j--) + printf("j = %d\n", j); + + /* Detta kommer dock att fungera eftersom j deklarerades + utanför for-loopen */ + printf("Utanför loopen är j = %d\n", j); + return 0; +} diff --git a/kapitel6/cmp-strings.c b/kapitel6/cmp-strings.c new file mode 100644 index 0000000..604aeea --- /dev/null +++ b/kapitel6/cmp-strings.c @@ -0,0 +1,21 @@ +#include +#include + +int main(void) +{ + char a[] = "Kalle"; + char b[] = "Lisa"; + + /* Skriver ut adressen till "Hej" */ + printf("%lu\n", (long unsigned int)"Hej"); + + /* Jämför strängar */ + if(strcmp(a, b) == 0) + printf("%s och %s är detsamma\n", a, b); + else if(strcmp(a, "Kalle") == 0) + printf("%s = Kalle\n", a); + else + printf("Ingen match\n"); + + return 0; +} diff --git a/kapitel6/continue-ex1.c b/kapitel6/continue-ex1.c new file mode 100644 index 0000000..478fa30 --- /dev/null +++ b/kapitel6/continue-ex1.c @@ -0,0 +1,13 @@ +#include + +int main(void) +{ + int i; + for (i=1; i<=10; i++) + { + if(i%2 == 0) + continue; + printf ("i = %d\n", i); + } + return 0; +} diff --git a/kapitel6/do-while-ex1.c b/kapitel6/do-while-ex1.c new file mode 100644 index 0000000..b4cfed2 --- /dev/null +++ b/kapitel6/do-while-ex1.c @@ -0,0 +1,14 @@ +#include + +int main(void) +{ + int x = 5; + + do + { + x++; + printf("X är nu: %d\n", x); + } while (x < 5); + + return 0; +} diff --git a/kapitel6/elseif-ex1.c b/kapitel6/elseif-ex1.c new file mode 100644 index 0000000..8a43755 --- /dev/null +++ b/kapitel6/elseif-ex1.c @@ -0,0 +1,21 @@ +#include + +int main(void) +{ + int a = 5; + int b = 10; + int c = 15; + + if (a > b) + printf("%d är större än %d\n", a, b); + else if (a > c) + printf("%d är större än %d\n", a, c); + else if (a == b) + printf("%d är lika stor som %d\n", a, b); + else + printf("Inget av de ovanstående villkoren var sanna\n"); + + printf("Här fortsätter koden som vanligt\n"); + + return 0; +} diff --git a/kapitel6/elseif-ex2.c b/kapitel6/elseif-ex2.c new file mode 100644 index 0000000..7b387a6 --- /dev/null +++ b/kapitel6/elseif-ex2.c @@ -0,0 +1,15 @@ +#include + +int main(void) +{ + int a = 10; + int b = 15; + + if (a < 20) + printf("Detta är den enda raden som kommer skrivas ut\n"); + else if (b < 20) + printf("Jag är också sann, men kommer inte skrivas ut\n"); + else + printf("Jag kommer inte heller skrivas ut...\n"); + return 0; +} diff --git a/kapitel6/enkelt-losenord.c b/kapitel6/enkelt-losenord.c new file mode 100644 index 0000000..ab29537 --- /dev/null +++ b/kapitel6/enkelt-losenord.c @@ -0,0 +1,16 @@ +#include +#include + +int main(void) +{ + char guess[10]; + char pass[] = "kalle"; + while (strcmp(guess, pass)) + { + printf("Skriv in lösenordet: "); + fgets(guess, sizeof(guess), stdin); + guess[strcspn(guess, "\n")] = '\0'; + } + printf("Du lyckades!\n"); + return 0; +} diff --git a/kapitel6/for-uteslut-ex1.c b/kapitel6/for-uteslut-ex1.c new file mode 100644 index 0000000..259e619 --- /dev/null +++ b/kapitel6/for-uteslut-ex1.c @@ -0,0 +1,13 @@ +#include + +int main(void) +{ + int i = 6; + i = i * 2; + + for ( ; i>0; i--) + { + printf("i = %d\n", i); + } + return 0; +} diff --git a/kapitel6/if-ex1.c b/kapitel6/if-ex1.c new file mode 100644 index 0000000..4efb8e0 --- /dev/null +++ b/kapitel6/if-ex1.c @@ -0,0 +1,13 @@ +#include + +int main(void) +{ + int a = 5; + int b = 10; + + if (a < b) + { + printf ("%d är mindre än %d\n", a, b); + } + return 0; +} diff --git a/kapitel6/if-ex2.c b/kapitel6/if-ex2.c new file mode 100644 index 0000000..8efe5b4 --- /dev/null +++ b/kapitel6/if-ex2.c @@ -0,0 +1,11 @@ +#include + +int main(void) +{ + int a = 5; + int b = 10; + + if (a < b) + printf ("%d är mindre än %d\n", a, b); + return 0; +} diff --git a/kapitel6/if-ex3.c b/kapitel6/if-ex3.c new file mode 100644 index 0000000..b3dbf77 --- /dev/null +++ b/kapitel6/if-ex3.c @@ -0,0 +1,8 @@ +#include + +int main(void) +{ + if (5 == (3+2)) + printf("5 är detsamma som 3+2\n"); + return 0; +} diff --git a/kapitel6/logiskt.c b/kapitel6/logiskt.c new file mode 100644 index 0000000..6e13ca9 --- /dev/null +++ b/kapitel6/logiskt.c @@ -0,0 +1,17 @@ +#include + +int main(void) +{ + /* Ger sant om antingen 4 > 5, eller om 5 < 10, + eller om både 4 > 5 och 5 < 10. Minst ett utav + villkoren måste således vara uppfyllda. */ + if (4 > 5 || 5 < 10) + printf("4 > 5 eller 5 < 10\n"); + + /* Ger sant om både 4 > 5 och 5 < 10, annars inte. + Båda villkoren måste således vara uppfyllda. */ + if (4 > 5 && 5 < 10) + printf("4 > 5 och 5 < 10\n"); + + return 0; +} diff --git a/kapitel6/oandlig-loop.c b/kapitel6/oandlig-loop.c new file mode 100644 index 0000000..d39ed5c --- /dev/null +++ b/kapitel6/oandlig-loop.c @@ -0,0 +1,10 @@ +#include + +int main(void) +{ + for (;;) + { + printf("En oändlig loop\n"); + } + return 0; +} diff --git a/kapitel6/rakna-upp.c b/kapitel6/rakna-upp.c new file mode 100644 index 0000000..f1258a5 --- /dev/null +++ b/kapitel6/rakna-upp.c @@ -0,0 +1,13 @@ +#include + +int main(void) +{ + int i; + + for (i=0; i<=10; i++) + { + printf("i = %d\n", i); + } + + return 0; +} diff --git a/kapitel6/tecken.c b/kapitel6/tecken.c new file mode 100644 index 0000000..a8c3994 --- /dev/null +++ b/kapitel6/tecken.c @@ -0,0 +1,12 @@ +#include + +int main(void) +{ + char tecken; + + if ((tecken = getchar()) == 10) + printf ("Inget tecken angavs\n"); + else + printf("Tecknet är: %c\n", tecken); + return 0; +} diff --git a/kapitel6/tecken_v2.c b/kapitel6/tecken_v2.c new file mode 100644 index 0000000..c5e0f85 --- /dev/null +++ b/kapitel6/tecken_v2.c @@ -0,0 +1,26 @@ +#include + +int main(void) +{ + char tecken; + + if ((tecken = getchar()) == 10) + printf ("Inget tecken angavs\n"); + else + { + printf("Tecknet är: %c\n", tecken); + if (tecken == 'A') + { + printf ("Du skrev ett versalt A\n"); + } + else if (tecken == 'a') + { + printf("Du skrev ett gement a\n"); + } + else + { + printf("Du skrev något tecken, förutom A eller a\n"); + } + } + return 0; +} diff --git a/kapitel6/tecken_v3.c b/kapitel6/tecken_v3.c new file mode 100644 index 0000000..90a8632 --- /dev/null +++ b/kapitel6/tecken_v3.c @@ -0,0 +1,22 @@ +#include + +int main(void) +{ + char tecken; + + if ((tecken = getchar()) == 10) + printf ("Inget tecken angavs\n"); + else + { + printf("Tecknet är: %c\n", tecken); + if ((tecken >= 65) && (tecken <= 90)) + printf("Det är dessutom en versal bokstav\n"); + else if ((tecken >= 97) && (tecken <= 122)) + printf("Det är dessutom en gemen bokstav\n"); + else if ((tecken >= 48) && (tecken <= 57)) + printf("Det är en siffra\n"); + else + printf("Tecknet är ingen bokstav och ingen siffra\n"); + } + return 0; +} diff --git a/kapitel6/veckodag.c b/kapitel6/veckodag.c new file mode 100644 index 0000000..4769510 --- /dev/null +++ b/kapitel6/veckodag.c @@ -0,0 +1,41 @@ +#include + +int main(void) +{ + int d; + + printf("Ange veckodag (1-7): "); + scanf("%d", &d); + + /* Kontrollera först om veckodagen är giltig */ + if((d<0) || (d>7)) + { + printf("Ogiltig veckodag, ange ett tal mellan 1-7\n"); + return 1; /* Avsluta programmet med returkod 1 + ifall veckodagen utanför 1-7 */ + } + + /* Nu använder vi switch för att behandla veckodagen */ + switch (d) + { + case(1): + printf("Början på veckan\n"); + break; + case(2): + printf("Tisdag\n"); + break; + case(5): + printf("Fredag!\n"); + break; + case(6): + printf("Lördag, det är helg!!\n"); + break; + case(7): + printf("Söndag, det är fortfarande helg!!\n"); + break; + default: + printf("Mitten av veckan...\n"); + break; + } + return 0; +} diff --git a/kapitel6/while-ex1.c b/kapitel6/while-ex1.c new file mode 100644 index 0000000..3c0c37d --- /dev/null +++ b/kapitel6/while-ex1.c @@ -0,0 +1,13 @@ +#include + +int main(void) +{ + int i = 10; + while (i>0) + { + printf ("i = %d\n", i); + i--; + } + + return 0; +} diff --git a/kapitel6/while-ex2.c b/kapitel6/while-ex2.c new file mode 100644 index 0000000..21e5d72 --- /dev/null +++ b/kapitel6/while-ex2.c @@ -0,0 +1,14 @@ +#include + +int main(void) +{ + int x = 5; + + while (x < 5) + { + x++; + printf("X är nu: %d\n", x); + } + + return 0; +} diff --git a/kapitel7/bitvis-negation-ex1.c b/kapitel7/bitvis-negation-ex1.c new file mode 100644 index 0000000..1357d99 --- /dev/null +++ b/kapitel7/bitvis-negation-ex1.c @@ -0,0 +1,13 @@ +#include + +int main(void) +{ + unsigned char a = 140; /* 1000 1100 */ + unsigned char b; + + b = ~a; + + printf("b = %d\n", b); /* 0111 0011 */ + + return 0; +} diff --git a/kapitel7/bitvis-negation-signerad.c b/kapitel7/bitvis-negation-signerad.c new file mode 100644 index 0000000..a70331d --- /dev/null +++ b/kapitel7/bitvis-negation-signerad.c @@ -0,0 +1,9 @@ +#include +int main(void) +{ + int a = 140; /* 0 1000 1100 */ + int b; + b = ~a; + printf("b = %d\n", b); /* 1 0111 0011 */ + return 0; +} diff --git a/kapitel7/bitvis-skift-ex1.c b/kapitel7/bitvis-skift-ex1.c new file mode 100644 index 0000000..d5c421f --- /dev/null +++ b/kapitel7/bitvis-skift-ex1.c @@ -0,0 +1,17 @@ +#include + +int main(void) +{ + unsigned char a = 16; /* 00010000 */ + + printf("%d\n", (a = a >> 1)); /* 8 = 00001000 */ + printf("%d\n", (a = a >> 1)); /* 4 = 00000100 */ + printf("%d\n", (a = a >> 2)); /* 1 = 00000001 */ + + printf("%d\n", (a = a << 1)); /* 2 = 00000010 */ + printf("%d\n", (a = a << 4)); /* 32 = 00100000 */ + printf("%d\n", (a = a << 1)); /* 64 = 01000000 */ + printf("%d\n", (a = a << 1)); /* 128 = 10000000 */ + + return 0; +} diff --git a/kapitel7/bitwise-and-or-ex1.c b/kapitel7/bitwise-and-or-ex1.c new file mode 100644 index 0000000..fd937f7 --- /dev/null +++ b/kapitel7/bitwise-and-or-ex1.c @@ -0,0 +1,16 @@ +#include + +int main(void) +{ + unsigned char a = 12; /* 0000 1100 */ + unsigned char b = 9; /* 0000 1001 */ + unsigned char c, d; + + c = a & b; + d = a | b; + + printf("OCH = %d\n", c); + printf("ELLER = %d\n", d); + + return 0; +} diff --git a/kapitel7/bitwise-and-or-ex2.c b/kapitel7/bitwise-and-or-ex2.c new file mode 100644 index 0000000..32d67f7 --- /dev/null +++ b/kapitel7/bitwise-and-or-ex2.c @@ -0,0 +1,14 @@ +#include + +int main(void) +{ + unsigned char a = 12; /* 0000 1100 */ + unsigned char b = 9; /* 0000 1001 */ + + if((a & b) == 8) + printf("Korrekt, talet blir åtta\n"); + if((a | b) == 13) + printf("Korrekt, talet blir tretton\n"); + + return 0; +} diff --git a/kapitel7/bitwise-and-or-ex3.c b/kapitel7/bitwise-and-or-ex3.c new file mode 100644 index 0000000..337a277 --- /dev/null +++ b/kapitel7/bitwise-and-or-ex3.c @@ -0,0 +1,11 @@ +#include + +int main(void) +{ + unsigned char x = 211; /* 1101 0011 */ + + if (x & 64) + printf("Den andra biten från vänster är satt\n"); + + return 0; +} diff --git a/kapitel7/bitwise-and-or-ex4.c b/kapitel7/bitwise-and-or-ex4.c new file mode 100644 index 0000000..76bde59 --- /dev/null +++ b/kapitel7/bitwise-and-or-ex4.c @@ -0,0 +1,13 @@ +#include + +int main(void) +{ + unsigned char a = 128; + unsigned char b; + + b = a | 1; + + printf("b = %d\n", b); + + return 0; +} diff --git a/kapitel7/exklusiv-eller.c b/kapitel7/exklusiv-eller.c new file mode 100644 index 0000000..1e03f8c --- /dev/null +++ b/kapitel7/exklusiv-eller.c @@ -0,0 +1,13 @@ +#include + +int main(void) +{ + unsigned char a = 147; + unsigned char b; + + b = a ^ 17; + + printf("b = %d\n", b); + + return 0; +} diff --git a/kapitel8/arsiffra.c b/kapitel8/arsiffra.c new file mode 100644 index 0000000..bb61f98 --- /dev/null +++ b/kapitel8/arsiffra.c @@ -0,0 +1,18 @@ +#include + +int arsiffra(char c) +{ + if ((c >= '0') && (c <= '9')) + return 1; + else + return 0; +} + +int main(void) +{ + char chr1 = '9'; + char chr2 = 'a'; + printf("chr1: %d\n", arsiffra(chr1)); + printf("chr2: %d\n", arsiffra(chr2)); + return 0; +} diff --git a/kapitel8/arsiffra_v2.c b/kapitel8/arsiffra_v2.c new file mode 100644 index 0000000..a26ecc0 --- /dev/null +++ b/kapitel8/arsiffra_v2.c @@ -0,0 +1,22 @@ +#include + +int arsiffra(char); /* Funktionsprototyp */ + +int main(void) +{ + char chr1 = '9'; + char chr2 = 'a'; + printf("chr1: %d\n", arsiffra(chr1)); + printf("chr2: %d\n", arsiffra(chr2)); + return 0; +} + +/* Här följer funktionskroppen för + funktionen arsiffra() */ +int arsiffra(char c) +{ + if ((c >= '0') && (c <= '9')) + return 1; + else + return 0; +} diff --git a/kapitel8/callbyvalue.c b/kapitel8/callbyvalue.c new file mode 100644 index 0000000..e0ac366 --- /dev/null +++ b/kapitel8/callbyvalue.c @@ -0,0 +1,18 @@ + #include + + int kvadrat(int x); + + int main(void) + { + int z = 5; + printf("z = %d\n", z); + printf("Kvadraten på z = %d\n", kvadrat(z)); + printf("z = %d\n", z); + return 0; + } + + int kvadrat(int x) + { + x = x * x; + return x; + } diff --git a/kapitel8/digit-test.c b/kapitel8/digit-test.c new file mode 100644 index 0000000..7898c2f --- /dev/null +++ b/kapitel8/digit-test.c @@ -0,0 +1,11 @@ +#include +#include + +int main(void) +{ + char chr1 = '9'; + char chr2 = 'a'; + printf("chr1: %d\n", isdigit(chr1)); + printf("chr2: %d\n", isdigit(chr2)); + return 0; +} diff --git a/kapitel8/omkrets.c b/kapitel8/omkrets.c new file mode 100644 index 0000000..d10827e --- /dev/null +++ b/kapitel8/omkrets.c @@ -0,0 +1,18 @@ +#include + +float omkrets(float diameter); + +int main(void) +{ + float d = 15; + float o = omkrets(d); + printf("Omkretsen för en cirkel med diametern " + "%.3f är %.3f\n", d, o); + return 0; +} + +float omkrets(float diameter) +{ + float pi = 3.14159265; + return (pi * diameter); +} diff --git a/kapitel8/primtal.c b/kapitel8/primtal.c new file mode 100644 index 0000000..18ea4d5 --- /dev/null +++ b/kapitel8/primtal.c @@ -0,0 +1,26 @@ +#include +#include "skrivprm.h" + +int main(void) +{ + int min; + int max; + + printf("Ange minsta talet: "); + if(!scanf("%d", &min)) + { + printf("Ange endast heltal\n"); + return 1; + } + + printf("Ange största talet: "); + if(!scanf("%d", &max)) + { + printf("Ange endast heltal\n"); + return 1; + } + + skrivprimtal(min, max); + + return 0; +} diff --git a/kapitel8/primtalsprogram.c b/kapitel8/primtalsprogram.c new file mode 100644 index 0000000..be1acd9 --- /dev/null +++ b/kapitel8/primtalsprogram.c @@ -0,0 +1,34 @@ +#include + +void skrivprimtal(int min, int max); + +int main(void) +{ + int a = 2; + int b = 30; + printf("Alla primtal mellan %d och %d\n", a, b); + skrivprimtal(a, b); + return 0; +} + + +void skrivprimtal(int min, int max) +{ + int i, j, primtal; + for (i=min; i<=max; i++) + { + primtal = 1; + for(j=2; j + +void skrivprimtal(int min, int max) +{ + int i, j, primtal; + for (i=min; i<=max; i++) + { + primtal = 1; + for(j=2; j + +void funk1(void); + +int main(void) +{ + int i = 555; + int x = 123; + printf("i utanför for: %d\n", i); + + for (int i = 0; i <= 2; i++) + { + printf("i inuti for: %d\n", i); + printf("x går att nå ifrån loopen och är: %d\n", x); + } + + printf("i utanför och efter for: %d\n", i); + funk1(); + printf("i i main är fortfarande: %d\n", i); + return 0; +} + +void funk1(void) +{ + int i = 999; + printf("i inuti funk1: %d\n", i); +} diff --git a/kapitel9/block-scope-ex2.c b/kapitel9/block-scope-ex2.c new file mode 100644 index 0000000..93b2eff --- /dev/null +++ b/kapitel9/block-scope-ex2.c @@ -0,0 +1,20 @@ +#include + +int main(void) +{ + int i = 10; + + for (int i = 0; i <= 3; i++) + { + printf("i inuti första for: %d\n", i); + } + + printf("i utanför for: %d\n", i); + + for ( ; i<= 13; i++) + { + printf("i inuti andra for: %d\n", i); + } + + return 0; +} diff --git a/kapitel9/calloc-ex1.c b/kapitel9/calloc-ex1.c new file mode 100644 index 0000000..326dee0 --- /dev/null +++ b/kapitel9/calloc-ex1.c @@ -0,0 +1,20 @@ +#include +#include +#include + +int main(void) +{ + char *a, *b; + a = calloc(30, sizeof(char)); + + strcat(a, "hej hej"); + printf("%s\n", a); + free(a); + + b = calloc(30, sizeof(char)); + strcat(b, "hej igen"); + printf("%s\n", b); + free(b); + + return 0; +} diff --git a/kapitel9/forsta-tecknet.c b/kapitel9/forsta-tecknet.c new file mode 100644 index 0000000..20a480a --- /dev/null +++ b/kapitel9/forsta-tecknet.c @@ -0,0 +1,30 @@ +#include +#include +#include +#define SIZE 20 + +int main(void) +{ + char *a; + int i; + a = calloc(SIZE, sizeof(char)); + strcpy(a, "Hej alla glada"); + + printf("Strängen: %s\n", a); + + *a = '\0'; /* "Initialisera" igen */ + printf("Strängen efter ny initialisering: %s\n", a); + + printf("\nTecken för tecken efter ny initialisering:\n"); + for (i=0; i + +extern int x; + +int main(void) +{ + printf("x = %d\n", x); + return 0; +} diff --git a/kapitel9/fungerande-scope-fil2.c b/kapitel9/fungerande-scope-fil2.c new file mode 100644 index 0000000..2a1b8e7 --- /dev/null +++ b/kapitel9/fungerande-scope-fil2.c @@ -0,0 +1,2 @@ +int x = 5; +static int y = 10; diff --git a/kapitel9/global-ex1.c b/kapitel9/global-ex1.c new file mode 100644 index 0000000..114f46a --- /dev/null +++ b/kapitel9/global-ex1.c @@ -0,0 +1,19 @@ +#include + +void funk(void); + +int x = 5; + +int main(void) +{ + printf("x = %d\n", x); + printf("++x = %d\n", ++x); + funk(); + printf("++x = %d\n", ++x); + return 0; +} + +void funk(void) +{ + printf("++x = %d\n", ++x); +} diff --git a/kapitel9/global-ex2.c b/kapitel9/global-ex2.c new file mode 100644 index 0000000..488c79c --- /dev/null +++ b/kapitel9/global-ex2.c @@ -0,0 +1,10 @@ +#include + +int x = 999; + +int main(void) +{ + int x = 100; + printf ("x = %d\n", x); + return 0; +} diff --git a/kapitel9/icke-fungerande-scope.c b/kapitel9/icke-fungerande-scope.c new file mode 100644 index 0000000..857c471 --- /dev/null +++ b/kapitel9/icke-fungerande-scope.c @@ -0,0 +1,15 @@ +#include + +extern int x; +extern int y; + +int main(void) +{ + /* Kommer inte att fungera eftersom + y är static i filen + fungerande-scope-fil2.c + */ + printf("x = %d\n", x); + printf("y = %d\n", y); + return 0; +} diff --git a/kapitel9/med-initialisering.c b/kapitel9/med-initialisering.c new file mode 100644 index 0000000..fc12613 --- /dev/null +++ b/kapitel9/med-initialisering.c @@ -0,0 +1,22 @@ +#include +#include +#include + +int main(void) +{ + char *a, *b; + a = malloc(300); + *a = '\0'; + + strcat(a, "hej hej"); + printf("%s\n", a); + free(a); + + b = malloc(30); + *b = '\0'; + strcat(b, "hej igen"); + printf("%s\n", b); + free(b); + + return 0; +} diff --git a/kapitel9/memset-ex1.c b/kapitel9/memset-ex1.c new file mode 100644 index 0000000..d20d3cf --- /dev/null +++ b/kapitel9/memset-ex1.c @@ -0,0 +1,15 @@ +#include +#include +#include + +int main(void) +{ + char *a; + a = malloc(30*sizeof(char)); + memset(a, '\0', 29); + strcat(a, "Hej svejs!"); + printf("%s\n", a); + memset(a, 'A', 15); + printf("%s\n", a); + return 0; +} diff --git a/kapitel9/minneshantering-ex1.c b/kapitel9/minneshantering-ex1.c new file mode 100644 index 0000000..13eacfd --- /dev/null +++ b/kapitel9/minneshantering-ex1.c @@ -0,0 +1,24 @@ +#include +#include +#include + +int main(void) +{ + char *meningen; + + /* Allokera minnet */ + meningen = malloc(sizeof(char)*24); + *meningen = '\0'; /* Initialisera strängen ("noll-terminera") */ + strcpy(meningen, "meningen med livet är"); + printf("%s\n", meningen); + + /* Utöka minnet till 'meningen' */ + meningen = realloc(meningen, sizeof(char)*40); + strcat(meningen, " att programmera"); + printf("%s\n", meningen); + + /* Frigör minnet */ + free(meningen); + + return 0; +} diff --git a/kapitel9/static-ex1.c b/kapitel9/static-ex1.c new file mode 100644 index 0000000..bdce366 --- /dev/null +++ b/kapitel9/static-ex1.c @@ -0,0 +1,18 @@ +#include + +void funk(void); + +int main(void) +{ + funk(); + funk(); + funk(); + return 0; +} + +void funk(void) +{ + int j = 0; + j++; + printf("%d\n", j); +} diff --git a/kapitel9/static-ex2.c b/kapitel9/static-ex2.c new file mode 100644 index 0000000..566e1ad --- /dev/null +++ b/kapitel9/static-ex2.c @@ -0,0 +1,18 @@ +#include + +void funk(void); + +int main(void) +{ + funk(); + funk(); + funk(); + return 0; +} + +void funk(void) +{ + static int j = 0; + j++; + printf("%d\n", j); +} diff --git a/kapitel9/strncpy-ex1.c b/kapitel9/strncpy-ex1.c new file mode 100644 index 0000000..39506a9 --- /dev/null +++ b/kapitel9/strncpy-ex1.c @@ -0,0 +1,15 @@ +#include +#include + +int main(void) +{ + char stor[20] = "Hej Kalle & Lisa!"; + char liten[10] = "XXXXXXXXX"; + + strncpy(liten, stor, sizeof(liten)-1); + + printf("stor = %s\n", stor); + printf("liten = %s\n", liten); + + return 0; +} diff --git a/kapitel9/testar-array.c b/kapitel9/testar-array.c new file mode 100644 index 0000000..1787ffc --- /dev/null +++ b/kapitel9/testar-array.c @@ -0,0 +1,28 @@ +#include + +int main(void) +{ + int i; + char a[5] = "B"; + char b[5] = { 0 }; + + printf("char a:\n"); + for (i = 0; i<5; i++) + { + if (a[i] == '\0') + printf("tecken: NULL\n"); + else + printf("tecken: %c\n", a[i]); + } + + printf("\nchar b:\n"); + for (i = 0; i<5; i++) + { + if (b[i] == '\0') + printf("tecken: NULL\n"); + else + printf("tecken: %c\n", b[i]); + } + + return 0; +} diff --git a/kapitel9/utan-initialisering.c b/kapitel9/utan-initialisering.c new file mode 100644 index 0000000..147ac50 --- /dev/null +++ b/kapitel9/utan-initialisering.c @@ -0,0 +1,20 @@ +#include +#include +#include + +int main(void) +{ + char *a, *b; + a = malloc(300); + + strcat(a, "hej hej"); + printf("%s\n", a); + free(a); + + b = malloc(30); + strcat(b, "hej igen"); + printf("%s\n", b); + free(b); + + return 0; +}