You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

不同操作系统换行符类型及统一替换为\0的技术咨询

Hey there! Let's tackle your two questions one by one, with practical fixes for your code.


1. Are there other newline characters we need to handle?

For modern development, the three newline formats you listed cover nearly all real-world scenarios:

  • \n (Line Feed): Used by Linux, modern macOS, and most Unix-like systems
  • \r\n (Carriage Return + Line Feed): Used by Windows and legacy DOS systems
  • \r (Carriage Return): Used by classic macOS (pre-OS X) and older iOS versions

There are extremely rare cases of legacy systems (like IBM mainframes using EBCDIC-based line endings) with obscure newline sequences, but these are almost never encountered today. Focusing on the three above will cover 99.9% of your use cases.


2. Fixing your code to strip unwanted newline characters

Looking at your code, there are a few key issues causing the leftover \r\n in your URL:

First: Critical typo in fgets

You passed buf as the third argument to fgets instead of the file pointer! That's breaking your read logic entirely. It should be:

fgets(buf, sizeof buf, file);

Second: Stripping newline characters reliably

fgets preserves newline characters from the file (text mode behavior varies by OS, so you can't rely on automatic conversion). To remove all \r and \n characters from your input, add this cleanup step right after reading the line:

// Remove any trailing \r or \n from the buffer
char *newline = strpbrk(buf, "\r\n");
if (newline != NULL) {
    *newline = '\0';
}

This works perfectly for URLs, which shouldn't contain internal newlines. If you ever need to remove all newlines (even mid-line), use this loop instead:

char *pos = buf;
while (*pos != '\0') {
    if (*pos == '\r' || *pos == '\n') {
        memmove(pos, pos + 1, strlen(pos));
    } else {
        pos++;
    }
}

Third: Fixing memory leaks and unsafe strncpy

  • Your current code leaks memory: it allocates a new url pointer each loop without freeing the old one. Always clean up existing memory first:
    if ((*properties)->url != NULL) {
        free((*properties)->url);
        (*properties)->url = NULL;
    }
    size_t buf_len = strlen(buf);
    (*properties)->url = (char *)malloc(buf_len + 1);
    if ((*properties)->url != NULL) {
        strcpy((*properties)->url, buf);
    }
    
  • strncpy is risky because it doesn't guarantee a null terminator if the source string matches the target buffer length. Instead, either use strcpy (if you know the target is large enough) or explicitly add a null terminator:
    // Example with a fixed-size target buffer
    #define MAX_URL_LENGTH 256
    strncpy(url, properties->url, MAX_URL_LENGTH - 1);
    url[MAX_URL_LENGTH - 1] = '\0'; // Ensure safe termination
    

Final revised code

Here's your code with all fixes applied:

FILE *file = fopen(filename, "rt");
if (file == NULL) {
    // Handle file open failure (e.g., log error, return early)
    return;
}

while (fgets(buf, sizeof buf, file) != NULL) {
    // Strip trailing newline characters
    char *newline = strpbrk(buf, "\r\n");
    if (newline != NULL) {
        *newline = '\0';
    }

    // Clean up previous URL memory to avoid leaks
    if ((*properties)->url != NULL) {
        free((*properties)->url);
    }

    // Allocate and copy the cleaned URL
    size_t url_len = strlen(buf);
    (*properties)->url = (char *)malloc(url_len + 1);
    if ((*properties)->url != NULL) {
        strcpy((*properties)->url, buf);
    }

    // ... Rest of your logic here
}

fclose(file); // Don't forget to close the file!

// Line x: Safe URL copy to target buffer
#define MAX_URL_BUFFER 256
strncpy(url, properties->url, MAX_URL_BUFFER - 1);
url[MAX_URL_BUFFER - 1] = '\0';

内容的提问来源于stack exchange,提问作者Sateesh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:40:14