Skip to content
C Basics: Remove Line Endings Without Trimming Spaces

C Basics: Remove Line Endings Without Trimming Spaces

November 1, 2026

A name or configuration value may contain meaningful spaces. Remove the line ending without applying a broad whitespace trim.

Prepare a scratch directory

Tested on Linux amd64 with GCC 14.2.0. Install GCC and make gcc available on PATH. You also need Bash, a text editor, and the standard mktemp, rm, and rmdir utilities. This example uses the C standard library.

Keep the same terminal open. Stop if setup fails, before saving the source:

start_directory="$PWD"
work_directory="$(mktemp -d)" || exit 1
cd -- "$work_directory" || exit 1

Run the example

Save this as trim-line-ending-demo.c:

#include <stdio.h>
#include <string.h>

int main(void) {
    char line[] = "  two words  \r\n";
    char unchanged[] = "no newline";
    size_t ending_position = strcspn(line, "\r\n");
    line[ending_position] = '\0';
    unchanged[strcspn(unchanged, "\r\n")] = '\0';
    printf("Value: [%s]\n", line);
    printf("Length: %zu\n", strlen(line));
    printf("Unchanged: [%s]\n", unchanged);
    return 0;
}

Compile and run it. The second command runs only after compilation succeeds:

gcc -std=c17 -Wall -Wextra -Werror -pedantic trim-line-ending-demo.c -o trim-line-ending-demo &&
./trim-line-ending-demo

Observed output:

Value: [  two words  ]
Length: 13
Unchanged: [no newline]

Read the result

strcspn returns the index of the first CR or LF. Replacing that byte with a null terminator hides the ending and everything after it while preserving leading, internal, and trailing spaces. If no ending is present, the returned length points to the existing terminator.

Apply it carefully

The array must be writable and already null-terminated. Do not use this on an arbitrary binary buffer or a string literal. It cuts at the first CR or LF, so it is appropriate for a single logical line, not a complete multiline document. If input came from fgets, handle read failure and overlong lines separately.

The official reference documents the behavior used here.

Clean up

Remove only the source and executable created for this example, then return to the starting directory:

rm -- trim-line-ending-demo.c trim-line-ending-demo
cd -- "$start_directory" || exit 1
rmdir -- "$work_directory"
unset start_directory work_directory

If the directory is not empty, inspect its remaining contents before removing anything else.

Acknowledgements

This post was created with assistance from AI.

Last updated on