# Files and Other Things --- CS 130 // 2021-09-15 ## Administrivia - Made progress on quiz 1 but unfortunately need to wait until next week to release the answers / grades # Assignment 2 # Questions ## ...about anything? # Review ## Stack Memory - **Stack memory** is the space where local variables, function calls, etc., are allocated - Locally scoped variables are freed when the code block they were defined in finishes ## Heap Memory - **Heap memory** persists between function calls + In C, we must manually create and destroy heap memory ## Heap Memory - `malloc(n)` creates `n` bytes of heap memory ```c // Creates an array on the heap with enough // space to hold 10 ints int *arr = malloc(10*sizeof(int)); ``` - `sizeof(int)` is the number of bytes of one `int` - `free(...)` is destroys heap memory ```c free(arr); // releases the memory ``` - Must call free on the pointer returned by `malloc` - These functions are in the `stdlib.h` library ## Exercise 1 - One convenient method in Python is the `str.join()` method. For example: ```py >>> " ".join(["The", "quick", "brown", "fox"]) "The quick brown fox" ``` - The prototype of the function would be: ```c // Takes an array of n strings and returns // a new string allocated on the heap char *join(char **arr, int n) ``` - Finish implementing this # `struct` / `typedef` ## Create a `struct` - A `struct` is a user-defined type that groups multiple values into one - Suppose we wanted a type to represent a 2D point: ```c struct point { double x; double y; }; ``` - Now we can create a `point` and modify it using: ```c struct point p; p.x = 5; p.y = 4; ``` ## Using `typedef` - The `typedef` keyword allows us to create aliases for types - It is commonly used to name structs: ```c typedef struct { double x; double y; } POINT; ``` ## Example: Euclidean Distance - $d = \sqrt{(x_1-x_2)^2 + (y_1-y_2)^2}$ --- ```c #include
double distance(POINT p1, POINT p2) { double xdiff = p1.x - p2.x; double ydiff = p1.y - p2.y; return sqrt(xdiff * xdiff + ydiff * ydiff); } ``` ## Using `math.h` - To compile a program that uses `math.h` you must explicitly tell `gcc` to include it: ```bash $ gcc distance.c -lm ``` - The `-lm` stands for "link math" ## Pointers to Structs - Suppose we have the following: ```c POINT p = {.x = 4, .y = 5}; ``` - We can define a **pointer** to `p1`: ```c POINT *pp = &p; ``` - To get the `x` and `y` coordinates out of `pp`, normally we'd have to do: ```c int x = (*pp).x; int y = (*pp).y; ``` ## Pointers to Structs - Pointers to structs are so common that there is a special operator to dereference and extract a field simultaneously ```c POINT p = {.x = 4, .y = 5}; POINT *pp = &p; int x = pp->x; // same as (*pp).x int y = pp->y; // same as (*pp).y ``` # Files ## Reading from a File - File reading/writing is included in `stdio.h` - To open a file in C, you use the `fopen` function: ```c FILE *fp = fopen("input.txt", "r"); ``` + The `"r"` opens the file for **reading** and the path is relative to the directory of your program ## Reading from a File - Once a file is open, you can **read** text from it using: ```c FILE *fp = fopen("input.txt", "r"); char buffer[80]; ``` ```c // Reads until a newline character is found. Similar to // the readline() method in Python. // Stops after 79 characters to not overfill the buffer fgets(buffer, 80, fp); ``` - `fgets` returns `buffer` if it reads at least one character and returns `NULL` otherwise - Just like Python, it **includes** the newline characters at the end of the string ## Looping Over a File - One common pattern is looping over a file: ```c FILE *fp = fopen("my_file.txt", "r"); char buffer[80]; while (fgets(buffer, 80, fp) != NULL) { // buffer contains the current line here } fclose(fp); ``` ## Writing to a File - To open a file for writing you use: ```c FILE *fp = fopen("input.txt", "w"); ``` + If `input.txt` already exists, it is deleted + If it doesn't exit, it is created - You can use `fprintf` to print to a file: ```c fprintf(fp, "%d %d %d\n", 100, 200, 300); ``` ## Closing Files - It is important to **close** your files to inform your OS that you're done with the file - You can do this with: ```c fclose(fp); ``` ## Exercise 2 - Suppose we have have some 2D points in a file - We could encode them in the following way: ```text 4 0 0 1 1 0 5 3.14 2.71 ``` - First line tells you how many points are in the file and then every other line is of the form `x y` ## Exercise 2 - Write a function called `read_points` with the following signature: ```c POINT *read_points(const char *filename) ``` - Should parse the file into an array of `POINT` objects - Remember to use `malloc` to allocate the memory on the heap!