0

Windows files end lines with "\r\n" instead of "\n" in Linux.

In my code I want to do string comparisons on what's in that line and thus do not want end-of-line characters. What's the best way to remove them?

One approach is to remove the last character (always '\n') and then do a check for the character before, and remove it if it matches '\r'. Is there a better approach?

Basically I want this file to return matches for line 1 and not line 2 or 3, whether the file was created in Linux or Windows:

String to generate a match: xxx

File (Linux or Windows) contents:

xxx
xxx1
xx
Lolo
  • 3,935
  • 5
  • 40
  • 50
  • 1
    The C standard I/O functions will handle mapping of newlines for text-files. All your program should see in memory should be plain newline `'\n'`. – Some programmer dude Apr 13 '22 at 10:17
  • 1
    One clean and safe way to universally do the removal is in this answer: [Removing trailing newline character from fgets() input](https://stackoverflow.com/questions/2693776/removing-trailing-newline-character-from-fgets-input/28462221#28462221). `buffer[strcspn(buffer, "\r\n")] = 0;` – Weather Vane Apr 13 '22 at 10:20

1 Answers1

-2

Use a function to trim trailing chars:

// tChars = "\r\n"
// You can alter it to return trimmed string length
static inline char*
trim_chars (char* const aPtr, const size_t aLen, const char *tChars) {
    if (!aPtr || aLen < 1 || !tChars) return aPtr;

    char *zPtr = aPtr + aLen - 1; // last character
    //Trimming trailing characters
    while (zPtr >= aPtr && strchr (tChars, (unsigned char) *zPtr))
        --zPtr;

    *(zPtr + 1) = '\0';
    return aPtr;
}

To test it :

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

#define MAX_TEST_STR 12
#define MAX_STR_LEN 16
#define TRIM_TRAIL_CHARS    "\r\n"

int main () {
    char str[MAX_TEST_STR][MAX_STR_LEN] = {
        "Test1 \n",
        "Test2 \n\n",
        "Test3 \r\n",
        "Test4 \n\r",
        "Test5 \n\r\r\r",
        "Test6 \n\r\n\r",
        "\n\r\n\r",
        "\r\n\r\n",
        "\r",
        "\n",
        "\r\n",
        "\n\r"
    };
    for (int si = 0; si < MAX_TEST_STR; ++si) {
        char * tstr = trim_chars(str[si], strlen(str[si]), TRIM_TRAIL_CHARS);
        printf ("%2d : [%s] len : %lu\n", si+1, tstr, strlen(tstr));
    }
    return 0;
}

And the trail-trimmed strings :

 1 : [Test1 ] len : 6
 2 : [Test2 ] len : 6
 3 : [Test3 ] len : 6
 4 : [Test4 ] len : 6
 5 : [Test5 ] len : 6
 6 : [Test6 ] len : 6
 7 : [] len : 0
 8 : [] len : 0
 9 : [] len : 0
10 : [] len : 0
11 : [] len : 0
12 : [] len : 0

What if getline() returns with embedded \n in strings on windows & embedded \r on linux? Go for strcspn() & handle the split string accordingly.

जलजनक
  • 3,072
  • 2
  • 24
  • 30