1.1 --- a/docs/src/modules.md Wed May 09 15:04:15 2018 +0200 1.2 +++ b/docs/src/modules.md Wed May 09 20:15:10 2018 +0200 1.3 @@ -108,6 +108,80 @@ 1.4 See the documentation of the macro constants in the header file for more 1.5 information. 1.6 1.7 +### Add line numbers to a file 1.8 + 1.9 +When reading a file line by line, you have three options: first, you could limit 1.10 +the maximum supported line length. 1.11 +Second, you allocate a god buffer large 1.12 +enough for the most lines a text file could have. 1.13 +And third, undoubtedly the best option, you start with a small buffer, which 1.14 +adjusts on demand. 1.15 +An `UcxBuffer` can be created to do just that for you. 1.16 +Just pass the `UCX_BUFFER_AUTOEXTEND` option to the initialization function. 1.17 +Here is a full working program, which adds line numbers to a file. 1.18 +```C 1.19 +#include <stdio.h> 1.20 +#include <ucx/buffer.h> 1.21 +#include <ucx/utils.h> 1.22 + 1.23 +int main(int argc, char** argv) { 1.24 + 1.25 + if (argc != 2) { 1.26 + fprintf(stderr, "Usage: %s <file>\n", argv[0]); 1.27 + return 1; 1.28 + } 1.29 + 1.30 + FILE* input = fopen(argv[1], "r"); 1.31 + if (!input) { 1.32 + perror("Canno read input"); 1.33 + return 1; 1.34 + } 1.35 + 1.36 + const size_t chunksize = 256; 1.37 + 1.38 + UcxBuffer* linebuf = 1.39 + ucx_buffer_new( 1.40 + NULL, // the buffer should manage the memory area for us 1.41 + chunksize, // initial buffer size should be the chunk size 1.42 + UCX_BUFFER_AUTOEXTEND); // the buffer will grow when necessary 1.43 + 1.44 + size_t lineno = 1; 1.45 + do { 1.46 + // read line chunk 1.47 + size_t read = ucx_stream_ncopy( 1.48 + input, linebuf, fread, ucx_buffer_write, chunksize); 1.49 + if (read == 0) break; 1.50 + 1.51 + // handle line endings 1.52 + do { 1.53 + sstr_t bufstr = ucx_buffer_to_sstr(linebuf); 1.54 + sstr_t nl = sstrchr(bufstr, '\n'); 1.55 + if (nl.length == 0) break; 1.56 + 1.57 + size_t linelen = bufstr.length - nl.length; 1.58 + sstr_t linestr = sstrsubsl(bufstr, 0, linelen); 1.59 + 1.60 + printf("%zu: %" PRIsstr "\n", lineno++, SFMT(linestr)); 1.61 + 1.62 + // shift the buffer to the next line 1.63 + ucx_buffer_shift_left(linebuf, linelen+1); 1.64 + } while(1); 1.65 + 1.66 + } while(1); 1.67 + 1.68 + // print the 'noeol' line, if any 1.69 + sstr_t lastline = ucx_buffer_to_sstr(linebuf); 1.70 + if (lastline.length > 0) { 1.71 + printf("%zu: %" PRIsstr, lineno, SFMT(lastline)); 1.72 + } 1.73 + 1.74 + fclose(input); 1.75 + ucx_buffer_free(linebuf); 1.76 + 1.77 + return 0; 1.78 +} 1.79 +``` 1.80 + 1.81 ## List 1.82 1.83 *Header file:* [list.h](api/list_8h.html)