读取txt文件时处理CRLF、CR和LF

读取txt文件时处理CRLF、CR和LF,c,newline,lf,C,Newline,Lf,我有一部分C代码,如下所示,是在linux gcc环境下编写的 在我的项目中,当读取从不同操作系统创建的txt文件时,我必须处理所有的CRLF、CR和LF 我不确定fscanf()是否自动处理所有情况 有没有其他方法可以处理所有案件 while (fscanf(fp, "%d", &data) != EOF) { printf("%d\n", data); } 读取从不同操作系统创建的txt文件时,处理所有CRLF、CR和LF 我不确定fscanf()是否自动处理所有案例 f

我有一部分C代码,如下所示,是在linux gcc环境下编写的

在我的项目中,当读取从不同操作系统创建的txt文件时,我必须处理所有的CRLF、CR和LF

我不确定fscanf()是否自动处理所有情况

有没有其他方法可以处理所有案件

while (fscanf(fp, "%d", &data) != EOF) 
{
    printf("%d\n", data);
}
读取从不同操作系统创建的txt文件时,处理所有CRLF、CR和LF

我不确定
fscanf()
是否自动处理所有案例

fscanf()
的某些用法可以正常工作,如
fscanf(fp、%d、&data)
,但不是全部

一个简单的替代方法是使用自己的
my_fgets()
读取输入行,然后调用
sscanf()

char my\u fgets(char*s,size\t sz,FILE*fp){
if(sz<1){
返回NULL;
}
char*org=s;
布尔无输入=真;
int ch=0;
而(-sz>0&(ch=fgetc(fp))!=EOF){
无输入=错误;
如果(ch='\r'){
int ch2=fgetc(fp);
如果(ch2!='\n')ungetc(ch2,fp);
打破
}
如果(ch='\n'){
打破
}
*s++=ch;
}
*s='\0';
if((ch==EOF)和&(no_输入| | |!feof(fp)))返回NULL;
返回组织;
} 
my_fgets(缓冲区、缓冲区大小、fp);
sscanf(缓冲器,…);
如果文件以二进制或文本模式打开,这将处理大多数情况



依赖文本模式和系统相关的行尾转换是不够的,因为代码需要处理至少3种情况,其中一些可能与预期的系统相关的行尾不一致。

您尝试过吗?所有的“换行符”都是空白。并且
“%d”
格式跳过了前导空格。此外,如果以文本模式打开文件,则系统在读取时应将任何与系统相关的行尾转换为纯换行
'\n'
(在写入时转换为相反的翻译).See@Someprogrammerdude在这里以文本模式打开文件对于OP案例是不够的。这或多或少是Kernighan和Pike在(1999)中使用的代码。这是你能做的最好的了。昨晚我碰巧在重读它,我突然想到,如果你在一个系统上进行终端输入,其中
\r
是行的结尾,那么
fgetc(fp)
读取一个额外的字符(看看它是否是新行)将挂起等待下一行。与管道数据类似;如果管道的远端发送该端的行
\r
,则代码将阻塞,等待另一个字符查看它是否为换行符。这不会影响您显示的内容;这是(正如我所说)可以做到最好的(没有任何关于预期行结束的额外知识)。“问题大多是理论上的而不是实际的。@JonathanLeffler幸运的是,OP暗示
fp
是一个文件,而不是
stdin
,但是你的阻塞点通常是有效的。我想知道你是否可以将
'\r'
视为始终以行结尾,而不测试下一个字符,以某种方式记录下,你用CR结束了一行,如果下一行的第一个字符是LF(NL),从新的输入行中省略它?这样可以避免阻塞;它可能需要一个围绕文件流的结构来保持上下文。@JonathanLeffler我会考虑这个想法
char my_fgets(char *s, size_t sz, FILE *fp) {
  if (sz < 1) {
    return NULL;
  }
  char *org = s;
  bool no_input = true;
  int ch = 0;

  while (--sz > 0 && (ch = fgetc(fp)) != EOF) { 
    no_input = false; 
    if (ch == '\r') {
      int ch2 = fgetc(fp);
      if (ch2 != '\n') ungetc(ch2, fp);
      break;
    }
    if (ch == '\n') {
      break;
    }
    *s++ = ch;
  }
  *s = '\0';
  if ((ch == EOF) && (no_input || !feof(fp))) return NULL;
  return org;
} 

my_fgets(buffer, sizeof buffer, fp);
sscanf(buffer, ...);