Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 不同操作系统中可能出现的新行字符有哪些_C - Fatal编程技术网

C 不同操作系统中可能出现的新行字符有哪些

C 不同操作系统中可能出现的新行字符有哪些,c,C,我们有一个逐行读取文件的代码,每一行都存储为字符串。问题是Linux在行的末尾添加了“\n”;windows在行的末尾添加“\r\n”,ios在行的末尾添加“\r”。我们想用'\0'替换所有这些特殊字符,以便获得字符串 其他操作系统是否添加了其他字符?我们需要处理这个问题 为了回应下面的评论,我尝试使用文本文件模式 file = fopen ( filename, "rt" ); while(fgets ( buf, sizeof buf, buf ) != NULL) { (*prop

我们有一个逐行读取文件的代码,每一行都存储为字符串。问题是Linux在行的末尾添加了“\n”;windows在行的末尾添加“\r\n”,ios在行的末尾添加“\r”。我们想用'\0'替换所有这些特殊字符,以便获得字符串

其他操作系统是否添加了其他字符?我们需要处理这个问题

为了回应下面的评论,我尝试使用文本文件模式

file = fopen ( filename, "rt" );
while(fgets ( buf, sizeof buf, buf ) != NULL)
{
    (*properties)->url= (char *) malloc(strlen(buf)+1);
    strcpy( (*properties)->url, buf);
/////...................more code

}

//line x-->
strncpy(url,properties->url,strlen(properties->url));
在x行,gdb打印 “\r\n\0”用于属性->url


当我的url为“

时,有三种相对常见的换行规则:
\r\n
\n
\r
,当编辑器对换行规则感到困惑时,可能会出现第四种换行规则,
\n\r
。如果一种方法支持通用换行符,那么它将同时支持所有四个换行符,即使是固定的

使用通用换行符支持逐行读取文件很容易。唯一的问题是,来自行缓冲源的交互式输入看起来像是延迟了一行读取。为了避免这种情况,可以将行读取到动态缓冲区中,最多可达,但不包括换行符;并在阅读下一行时使用换行符。例如:

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

ssize_t  getline_universal(char **dataptr, size_t *sizeptr, FILE *in)
{
    char   *data = NULL;
    size_t  size = 0;
    size_t  used = 0;
    int     c;

    if (!dataptr || !sizeptr || !in) {
        errno = EINVAL;
        return -1;
    }

    if (*sizeptr) {
        data = *dataptr;
        size = *sizeptr;
    } else {
        *dataptr = data;
        *sizeptr = size;
    }

    /* Ensure there are at least 2 chars available. */
    if (size < 2) {
        size = 2;
        data = malloc(size);
        if (!data) {
            errno = ENOMEM;
            return -1;
        }
        *dataptr = data;
        *sizeptr = size;
    }

    /* Consume leading newline. */
    c = fgetc(in);
    if (c == '\n') {
        c = fgetc(in);
        if (c == '\r')
            c = fgetc(in);
    } else
    if (c == '\r') {
        c = fgetc(in);
        if (c == '\n')
            c = fgetc(in);
    }

    /* No more data? */
    if (c == EOF) {
        data[used] = '\0';
        errno = 0;
        return -1;
    }

    while (c != '\n' && c != '\r' && c != EOF) {

        if (used + 1 >= size) {
            if (used < 7)
                size = 8;
            else
            if (used < 1048576)
                size = (3 * used) / 2;
            else
                size = (used | 1048575) + 1048577;

            data = realloc(data, size);
            if (!data) {
                errno = ENOMEM;
                return -1;
            }

            *dataptr = data;
            *sizeptr = size;
        }

        data[used++] = c;
        c = fgetc(in);
    }

    /* Terminate line. We know used < size. */
    data[used] = '\0';

    /* Do not consume the newline separator. */
    if (c != EOF)
        ungetc(c, in);

    /* Done. */
    errno = 0;
    return used;
}

请注意,因为
free(NULL)
是安全的,所以在调用
getline\u universal(&line\u buf,&line\u max,stream)之前,可以丢弃缓冲区(使用
free(line\u buf);line\u buf=NULL;line\u max=0;
)。查看悬赏奖的答案。不幸的是,几乎没有办法涵盖所有未知的异国情调操作系统(那些由一些愚昧的狂人设计的)。您可能应该首先将范围限制在成熟的操作系统上。其他操作系统是否添加了其他字符?我们需要处理这个问题。为什么?C标准有一个明确定义的“文本”模式,用于将所有换行符转换为
\n
字符的流,您的问题是您将其作为二进制文件读取。如果您将其作为文本文件读取或写入,那么您就不在乎操作系统如何解释“\n”。祝您好运,在一个文件上用NUL替换操作系统提供的记录(行)边界。您为什么不能简单地执行
bool new\u line=false;if(isspace(ch)){while(ch='\n'| | ch='\r'{new_line=true;ch=fgetc(in);}}
?@Lundin:这也会跳过(消耗)空行。如果您检查提供的bool变量,则不会。@Lundin:the循环
而(ch='\n'| ch='\r'{new u line=true;ch=fgetc(in)}
最肯定消耗空行。这就是为什么我没有使用它。如前所述,我的答案中的代码即使使用行缓冲的交互式输入也可以正常工作,并且不会跳过空行。它唯一的缺点是,它使用换行符时没有告诉调用方确切的换行符类型。“函数的工作原理很像…getline()”还有其他区别:它可以设置
errno=0
——这是最意想不到的。它在流中保留行结束字符。如果最后一行是空行,则返回-1。
int main(void)
{
    unsigned long  linenum = 0u;
    char          *line_buf = NULL;
    size_t         line_max = 0;
    ssize_t        line_len;

    while (1) {
        line_len = getline_universal(&line_buf, &line_max, stdin);
        if (line_len < 0)
            break;

        linenum++;

        printf("%lu: \"%s\" (%zd chars)\n", linenum, line_buf, line_len);
        fflush(stdout);
    }

    if (errno) {
        fprintf(stderr, "Error reading from standard input: %s.\n", strerror(errno));
        return EXIT_FAILURE;
    }

    /* Not necessary before exiting, but here's how to
       safely discard the line buffer: */
    free(line_buf);
    line_buf = NULL;
    line_max = 0;
    line_len = 0;

    return EXIT_SUCCESS;
}