读取txt文件时处理CRLF、CR和LF
我有一部分C代码,如下所示,是在linux gcc环境下编写的 在我的项目中,当读取从不同操作系统创建的txt文件时,我必须处理所有的CRLF、CR和LF 我不确定fscanf()是否自动处理所有情况 有没有其他方法可以处理所有案件读取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
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, ...);