Converting fixed-width text file to CSV in C
Consider const char *

const char *source allows the function to be used with const strings, better conveys code's functionality and more readily allows for optimizations.

// int trimcpy(char *destination, char *source, size_t len) {
int trimcpy(char *destination, const char *source, size_t len) {


Undefined behavior

trimcpy() begins by examining later elements of source[] even though they are not known to have been assigned.  The string may not be as long as len.

int trimcpy_alt(char *destination, char *source, size_t len) {
   // Suggest memchr() here rather than strlen() to not look too far.
   char *null_character_pos = memchr(source, '\0', len);
   if (null_character_pos) len = null_character_pos - source;
   ...


Undefined behavior 2

In a selective case of an empty file, the first call to fgets() returns NULL and then the following fputs(out, wfp); is UB as out contents are not initialized.  Add initialization or assignment.

char out[BUFFER_SIZE];
out[0] = '\0'; // add


Not trimming end spaces before \n

trimcpy() does not trim spaces just before '\n'.  I suspect this in not in line with OP's goals.

Avoid redundant information

Redundant information takes more work to maintain.   Consider dropping the 3

// #define COLS 3
size_t RANGES[][2] = {{0, 6}, {6, 20}, {29, 3}};
#define COLS (sizeof RANGES/sizeof RANGES[0])




Minor things:

Mixing types

Little reason to mix size_t and int types here for array indexing and sizing.  Recommend to  use just one: size_t (my preference) or 2) int, but not  both.

// From
int trimcpy(char *destination, char *source, size_t len) {
  ...
  int i = 0;
  while (i&lt;len &amp;&amp; *source != '\0') {

// To
size_t trimcpy(char *destination, char *source, size_t len) {
  ...
  size_t i = 0;
  while (i&lt;len &amp;&amp; *source != '\0') {


main()  

  // int p = 0;
  size_t p = 0;




Subtraction with unsigned types

If above size_t employed, consider the 2 below:  Which works well should a later version of code surprisingly  define  #define BUFFER_SIZE 19?

if (p &gt; BUFFER_SIZE - 20) {
if (p + 20 &gt; BUFFER_SIZE) {



   The first is the same as if (p &gt; SIZE_MAX) { or if (0) {