From 0c2e23ea497d5e83cd1b518cd597628ba35f46d8 Mon Sep 17 00:00:00 2001 From: zlg Date: Wed, 11 Sep 2013 06:49:22 -0500 Subject: Solve Exercise 5-7: Improved readlines() --- ch5/5-07_readlines-v2.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 ch5/5-07_readlines-v2.c diff --git a/ch5/5-07_readlines-v2.c b/ch5/5-07_readlines-v2.c new file mode 100644 index 0000000..f5d1316 --- /dev/null +++ b/ch5/5-07_readlines-v2.c @@ -0,0 +1,106 @@ +#include +#include + +/* The C Programming Language: 2nd Edition + * + * Exercise 5-7: Rewrite readlines to store lines in an array supplied by + * main rather than calling alloc to maintain storage. How much faster is + * the program? + * + */ + +#define MAXLINES 5000 +#define MAXLEN 1000 +#define MAXBUF 500000 + +// An additional argument is needed so we can store addresses +int readlines(char *lineptr[], int nlines, char *in_lines); +void writelines(char *lineptr[], int nlines); +int get_line(char line[], int lim); +void q_sort(char *v[], int left, int right); +void swap(char *v[], int i, int j); + +char *lineptr[MAXLINES]; + +int main() { + char line_store[MAXBUF]; // this is our buffer for storing lines + int nlines; + if ((nlines = readlines(lineptr, MAXLINES, line_store)) >= 0) { + q_sort(lineptr, 0, nlines - 1); + writelines(lineptr, nlines); + return 0; + } else { + printf("error: input too big to sort\n"); + return 1; + } +} + +/* The third argument allows us to set and reference pointers to it so the + * data inside it has structure, which is maintained by the pointers in + * lineptr[]. Each time we start a new line, the current address of + * line_store is stored, the text is stored in the buffer, and the process + * repeats. While this (arguably) uses more RAM (the buffer's rather large), + * it's marginally faster due to the allocation of RAM only one time as + * opposed to x times, where x is the number of lines processed. + */ +int readlines(char *lineptr[], int maxlines, char *line_store) { + int len, nlines, total; + char line[MAXLEN]; + nlines = 0; + total = 0; // number of characters processed + while ((len = get_line(line, MAXLEN)) > 0) { + if (nlines >= maxlines || total >= MAXBUF) { + return -1; + } else { + total += len; + line[len - 1] = '\0'; + lineptr[nlines++] = line_store; // copy the current spot to the array of pointers + strncpy(line_store, line, len); // copy line into line_store + line_store += len; // advance to the next available spot + } + } + return nlines; +} + +void writelines(char *lineptr[], int nlines) { + while (nlines-- > 0) { + printf("%s\n", *lineptr++); + } +} + +void q_sort(char *v[], int left, int right) { + int i, last; + if (left >= right) { + return; + } + swap(v, left, (left + right) / 2); + last = left; + for (i = left + 1; i <= right; i++) { + if (strcmp(v[i], v[left]) < 0) { + swap(v, ++last, i); + } + } + swap(v, left, last); + q_sort(v, left, last - 1); + q_sort(v, last + 1, right); +} + +void swap(char *v[], int i, int j) { + char *temp; + temp = v[i]; + v[i] = v[j]; + v[j] = temp; +} + +int get_line(char s[], int lim) { + int c, i; + for (i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; ++i) { + s[i] = c; + } + if (c == '\n') { + s[i] = c; + ++i; + } + s[i] = '\0'; + return i; +} -- cgit v1.2.3-70-g09d2 ns'>-3/+19 Users can copy these files and use them to publish their VGStash collection. 2025-07-29The big VGStash-Web commit!zlg5-0/+658 This commit introduces a templated HTML file to insert your username, and a set of files that, when combined with your exported VGStash in JSON format, can be used to display (and browse) your game collection in your Web browser! 2025-07-29README.md: Better clarify dates, add contact detailszlg1-7/+19 2025-07-29README.md: Remove references to -w flag to 'list' commandzlg1-2/+2 2025-07-28Update build system, release 0.3beta8v0.3b8zlg3-6/+6 Target Python version is now 3.13, and built with `python -m build`. 2025-07-27README.md: update to include mentions of *_date fieldszlg1-7/+26 2025-07-27Finish integrating support for p_date, et alzlg2-23/+59 * Tightened up update_game() to use explicit fields * 'unowned' and 'unbeatable' status now show as blank fields in list_game() output * Results are counted and a proper message is emitted instead of erroring when there are no results. * Support p_date, b_date, and c_date in the CLI 2025-01-24Add support for p_date, b_date, c_date to CLIzlg2-48/+136 The library and CLI tool both can handle the new schema v2 that includes these columns. Please use the schema migration script in the "scripts" directory to continue using VGStash. The list_games function has been completely re-worked to handle arbitrary tabular data. Raw mode has remained, but the width switch (-w) for default table view is no longer present. The first VIEW supporting these columns is also available in FILTERS: the backlog_age filter, which will show you the amount of time games with a purchase date value have been sitting in your collection unbeaten. 2025-01-24tox.ini: Update to Python 3.11 env by defaultzlg1-1/+1 2025-01-23schema1-to-2.py: Add shebang because I'm a doofuszlg1-0/+2 2023-09-22scripts: Add schema v1->v2 migration scriptzlg2-9/+85 This script adds three columns to the schema, supporting the "Purchased", "Beaten", and "Completed" note headers. They are now converted to a UNIX timestamp and stored in a separate column so queries made against that metadata are easier. The library itself still needs to support all the new columns.