From 2084b2ae842e5ceeeba6950ffb6d8b6ac70b51fb Mon Sep 17 00:00:00 2001 From: Reina Harrington-Affine Date: Tue, 16 Sep 2025 18:54:10 +0000 Subject: [PATCH] WIP version of ex1-17-2.c that crashes during a memory safety check in store() for some reason. If I comment out the check, it spins and segfaults. Cause unknown. --- KNR C/ex1-17-2.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 KNR C/ex1-17-2.c diff --git a/KNR C/ex1-17-2.c b/KNR C/ex1-17-2.c new file mode 100644 index 0000000..25c56f8 --- /dev/null +++ b/KNR C/ex1-17-2.c @@ -0,0 +1,94 @@ +#include +#include + +// Initialize array for bulk storage of incoming text. . . +char buffer[32000] = {0}; +char output[64000] = {0}; + +//Global information about the state of output[] to circumvent costly seeking +//of double null by loop. +int outputCrsr = 0; +int* locOutCrsr = &outputCrsr; + +// Function for storing from the input buffer to array +void store(char storage[]); +// Function for sorting through data in buffer[] +void enumerate(char data[]); +// Function for recalling and printing data identified for recall by enumerate() +void recall(char from[]); +// Function to copy from one array to another +void replicate(char from[], char to[]); + +int main(){ + store(buffer); // Calls store() to write from stdin to storage + enumerate(buffer);// Calls enumerate() to seek and enumerate lines of + // length 80 or greater. + recall (output); //calls recall() to print output[] to stdout + return 0; +} + +// Important to note that store intentionally does not print EOF to the storage +void store(char storage[]){ + int cursor = 0; + int lim = 32000; //TODO Un-hardcode this. Using strlen resulted in a spin + //due to interactions with a memory safety check in a + //previous version. + for(int current = getchar(); current != EOF; ++cursor){ + // Begin memory safety check. . . + if (cursor >= (lim - 1)){ + printf("%s", "Error: Input exceeds size of storage (32kB)."); + exit(EXIT_FAILURE); + } + storage[cursor] = current; + } +} + +// Enumerate breaks on first encountered null character (i.e. end of used space +//in data[] +void enumerate(char data[]){ + + int curLineLen = 0; // Current line length (characters since last newline) + int dataCursor = 0; // Currently accessed position in data[] + char workingStorage[32000]; // Local storage for enumerate while working + int wSCursor = 0; // Currently accessed position in workingStorage[] + + for(int current = data[dataCursor]; current != '\0'; ++dataCursor){ + if(current != '\n'){ + workingStorage[wSCursor] = current; + ++curLineLen; + } else if (current == '\n' && curLineLen >= 80){ + workingStorage[wSCursor] = current; + ++wSCursor; + workingStorage[wSCursor] = '\0'; + replicate(workingStorage, output); + } else if (current == '\n' && curLineLen < 80){ + wSCursor = 0; + } + } +} + +//TODO Shift internal cursor to first double null in output[], increment cursor, +//and write new data to output[]. Break on first encountered input null. +void replicate(char from[], char to[]){ + +//TODO Malloc a variable inside replicate() to replace outputCrsr and locOutCrsr +//because the fact that replicate() depends on global variables like that is a +//readability nightmare. This is the only fucntion that depends on them. + + int toCrsr = 0; + int fromCrsr = 0; + int last = 0; + + toCrsr = outputCrsr; //Shift toCrsr to the last written position in output. + ++toCrsr; //Step forward 1 byte in to[] in order to preserve a null space + + for(int current = from[fromCrsr]; current != '\0'; ++fromCrsr){ + to[toCrsr] = from[fromCrsr]; + ++toCrsr; + } + *locOutCrsr = toCrsr; //Set global state of output. +} + +void recall(char from[]){ + printf("%s", from); +}