HiveBrain v1.2.0
Get Started
← Back to all entries
patterncMinor

A trivial command line utility for trimming whitespace from lines in C

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
linewhitespacetrimmingutilitytrivialforcommandfromlines

Problem

I was practicing some C and decided to write this simple command line utility for stripping leading and trailing white-space characters.

Note: see the next iteration at A trivial command line utility for trimming whitespace from lines in C - follow-up

The code:

```
#include
#include
#include
#include

#define LINE_LENGTH 8096

#define HELP_MESSAGE "Usage: trim [FILE1, [FILE2, [...]]]\n" \
" If no files specified, reads from standard input.\n"

#define VERSION_MESSAGE "trim 1.6\n" \
"By Rodion \"rodde\" Efremov. 07.04.2015 Helsinki\n"

#define HELP_FLAG "-h"
#define VERSION_FLAG "-v"

/*****
This routine removes all leading and trailing whitespace from a string,
doing that in-place. (
/
static char trim_inplace(char const start)
{
size_t leading_ws_chars = 0;
size_t trailing_ws_chars = 0;
size_t len;
size_t i;

// Find amount of leading whitespace characters.
while (isspace(*(start + leading_ws_chars)))
{
++leading_ws_chars;
}

// Find the length of the entire string.
len = leading_ws_chars;

while (start[len])
{
++len;
}

if (len == leading_ws_chars)
{
// Empty string.
start[0] = '\0';
}

// Here 'start[len] == NULL'.
while (isspace(*(start + len - 1 - trailing_ws_chars)))
{
++trailing_ws_chars;
}

// Shift the text to the left.
for (i = 0; i < len - leading_ws_chars - trailing_ws_chars; ++i)
{
start[i] = start[i + leading_ws_chars];
}

// Terminate.
start[len - leading_ws_chars - trailing_ws_chars] = '\0';
return start;
}

/*****
* Processes a file.

Solution

I can't help you with GNU style, but here are some things that may help you improve your code.

Close files when you are done with them

The program will automatically close files when the program terminates, but it's good to close them as soon as you're done with them. This helps prevent the problem of running out of file handles.

Simplify the trim_inplace function

The trim_inplace function can be simplfified considerably. One possibility is this:

static char* trim_inplace(char *start) 
{
   // handle empty line per @Snowbody's commment
    if (strlen(start) == 0)  
        return start;

    for (char *end = &start[strlen(start)-1]; isspace(*end); --end) 
        *end = '\0';
    while (isspace(*start))
        ++start;
    return start;
}


Don't use const if you don't mean it

The program declares this function:

static char* trim_inplace(char *const start)


But that doesn't make much sense. It says "I can alter the characters, but I won't alter the pointer" but that doesn't really make much sense because the pointer is passed by value anyway. The same is true for the process_file argument.

See this SO question for details on that latter point.

Consider handling arbitrarily long lines

As the program is currently written, it has an arbitrary limit of 8096 characters for a line. If I have a line with 8094 spaces followed by the string "ab", the program will trim the spaces, but put "a" and "b" on separate lines in the output. The program could easily be rewritten to handle character at a time input and eliminate the arbitrary line limit.

Eliminate return EXIT_SUCCESS at the end of main

For a long time now, the C language says that finishing main will implicitly generate the equivalent to return EXIT_SUCCESS. For that reason, you should eliminate that line from your code.

Code Snippets

static char* trim_inplace(char *start) 
{
   // handle empty line per @Snowbody's commment
    if (strlen(start) == 0)  
        return start;

    for (char *end = &start[strlen(start)-1]; isspace(*end); --end) 
        *end = '\0';
    while (isspace(*start))
        ++start;
    return start;
}
static char* trim_inplace(char *const start)

Context

StackExchange Code Review Q#86140, answer score: 6

Revisions (0)

No revisions yet.