C 将文件中的多个新行替换为一行
此函数用于在文本文件中搜索新行字符。当找到换行符时,它会增加<代码>新行< /代码>计数器,并且当有超过2个连续的空白新行时,它假设将所有空行压缩为一个空行。 在我的代码中,如果有两个新行,则假设它将它们去掉并压缩成一行,出于测试目的,我还让它在达到C 将文件中的多个新行替换为一行,c,file,C,File,此函数用于在文本文件中搜索新行字符。当找到换行符时,它会增加新行< /代码>计数器,并且当有超过2个连续的空白新行时,它假设将所有空行压缩为一个空行。 在我的代码中,如果有两个新行,则假设它将它们去掉并压缩成一行,出于测试目的,我还让它在达到新行
新行<2
条件时打印“新行”。现在,它为每一行打印新行,不管是否为空,并且它不会删除额外的新行。我做错了什么
编辑:这是我的完整代码
因此,基本上,程序假设将两个文件连接在一起,然后对它们执行各种操作,就像我试图做的那样,去掉多个连续的空白新行。
所以为了在cygwin中执行它,我需要
/a-s文件1文件2
假设将file1和file2连接到一个名为contents.txt的文件中,然后去掉连续的新行并将它们显示在我的cygwin终端(stdout)上。(s调用函数以除去连续的行)。传入的第三个和第四个参数(file1和file2)是两个文件,假设它们连接在一起形成一个名为contents.txt的文件。挤压线函数读取contents.txt文件,并假设挤压新行。下面是我放入file1.txt的内容示例。file2.txt只是有一堆单词,后跟空的新行
int newLine = 1;
int c;
if ((fileContents = fopen("fileContents.txt", "r")) == 0)
{
perror("fopen");
return 1;
}
while ((c = fgetc(fileContents)) != EOF)
{
if (c == '\n')
{
newLine++;
if (newLine < 2)
{
printf("new line");
putchar(c);
}
}
else
{
putchar(c);
newLine = 0;
}
}
int新行=1;
INTC;
if((fileContents=fopen(“fileContents.txt”,“r”))==0)
{
佩罗尔(“福彭”);
返回1;
}
while((c=fgetc(fileContents))!=EOF)
{
如果(c=='\n')
{
换行符++;
如果(换行符<2)
{
printf(“新线”);
普查尔(c);
}
}
其他的
{
普查尔(c);
换行=0;
}
}
程序读取的包含这些内容的.txt文件。它假设读取文件,去掉前导的和连续的新行,并将新的格式化内容输出到cywgin终端上的标准输出
/* hello world program */
#include <stdio.h>
tab
2tabs
/*你好世界计划*/
#包括
标签
2塔斯
干运行代码:
如果文件以换行符开头,且换行符
为1
:
对于第一次迭代:
if (c == '\n') //Will be evaluated as true for a new-line character.
{
newLine++; //newLine becomes 2 before next if condition is evaluated.
if (newLine < 2) //False, since newLine is not less than 2, but equal.
{
printf("new line");
putchar(c);
}
}
else //Not entered
{
putchar(c);
newLine = 0;
}
if(c=='\n')//对于新行字符将被计算为true。
{
换行符+++;//如果计算条件,换行符在下一个条件之前变为2。
if(换行符<2)//False,因为换行符不小于2,但相等。
{
printf(“新线”);
普查尔(c);
}
}
else//未输入
{
普查尔(c);
换行=0;
}
在第二次迭代中:(假设它是一个连续的换行字符)
if(c=='\n')//对于新行字符将被计算为true。
{
换行符+++;//如果计算条件,换行符在下一个条件之前变为3。
if(换行符<2)//False,因为换行符大于2。
{
printf(“新线”);
普查尔(c);
}
}
else//未输入
{
普查尔(c);
换行=0;
}
所以
- 将
初始化为newLine
0
input: '\n\n\naa\nbb\n\ncc'
output: aa'\n'
bb'\n' //notice, there is no blank line here
cc
如果这是目标,那么您的代码逻辑是正确的
- 通过定义
,它将删除 输入文本newLine=1
- 当处理后仍有一个“\n”时,它将输出一个
,给出提示新行
if (c == '\n')
{
newLine++;
if (newLine < 3) // here should be 3 to print '\n' twice,
// one for 'aaa\n', one for blank line
{
//printf("new line");
putchar(c);
}
}
[已编辑]
最小的变化是:
if ( newLine <= 2)
诊断
如果有Unix行结尾,逻辑看起来是正确的。如果您有Windows CRLF行结尾,但在Unix上处理文件,则在每个LF之前都有一个CR,并且CR将换行符
重置为零,这样您就可以获得每个换行符的消息
这可以解释你看到了什么
这也可以解释为什么其他人都说你的逻辑是正确的(前提是行的结尾只有LF而不是CRLF),但是你看到了一个意想不到的结果
如何解决
公平的问题。一个主要选项是使用dos2unix
或等效机制将DOS文件转换为Unix文件。在这个问题上有很多问题
如果您根本不需要CR('\r'
在C中)字符,您可以简单地删除(不打印,也不为零换行符
)这些字符
如果需要保留CRLF行结尾,则需要更加小心。你必须记录你有一个CR,然后检查你有一个LF,然后打印这对,然后检查你是否有更多的CRLF序列并抑制它们,等等
工作代码-dupnl.c
该程序只读取标准输入;这比以前更灵活
仅从固定文件名读取。学会避免编写
仅适用于一个文件名;它将为您节省大量的重新编译
随着时间的推移。Th代码仅处理带有换行符(“\n”
)的Unix样式文件
最后;它还处理带有CRLF(“\r\n”
)结尾的DOS文件;和
它还使用CR处理(旧式)Mac(Mac OS 9及更早版本)文件
(“\r”
)行结尾。事实上,它处理任意交错
aaa'\n' //1st line, there is a '\n' append to 'aaa'
'\n' //2nd line, blank line
bbb'\n' //3rd line, there is a '\n' append to 'bbb'
'\n' //4th line, blank line
ccc //5th line,
if (c == '\n')
{
newLine++;
if (newLine < 3) // here should be 3 to print '\n' twice,
// one for 'aaa\n', one for blank line
{
//printf("new line");
putchar(c);
}
}
while ((c = fgetc(fileContents)) != EOF)
{
if ( c == '\r') continue;// add this line to discard possible '\r'
if (c == '\n')
{
newLine++;
if (newLine < 3) //here should be 3 to print '\n' twice
{
printf("new line");
putchar(c);
}
}
else
{
putchar(c);
newLine = 0;
}
}
if ( newLine <= 2)
int c;
int duplicates=0;
while ((c = fgetc(fileContents)) != EOF)
{
if (c == '\n') {
if (duplicates > 1) continue;
duplicates++;
}
else {
duplicates=0;
}
putchar(c);
}
#include <stdio.h>
int main(void)
{
FILE *fp = stdin; // Instead of fopen()
int newLine = 1;
int c;
while ((c = fgetc(fp)) != EOF)
{
if (c == '\n')
{
/* Unix NL line ending */
if (newLine++ == 0)
putchar(c);
}
else if (c == '\r')
{
int c1 = fgetc(fp);
if (c1 == '\n')
{
/* DOS CRLF line ending */
if (newLine++ == 0)
{
putchar(c);
putchar(c1);
}
}
else
{
/* MAC CR line ending */
if (newLine++ == 0)
putchar(c);
if (c1 != EOF && c1 != '\r')
ungetc(c1, stdin);
}
}
else
{
putchar(c);
newLine = 0;
}
}
return 0;
}
$ cat test.unx
data long enough to be seen 1 - Unix
data long enough to be seen 2 - Unix
data long enough to be seen 3 - Unix
data long enough to be seen 4 - Unix
data long enough to be seen 5 - Unix
$ sed 's/Unix/DOS/g' test.unx | ule -d > test.dos
$ cat test.dos
data long enough to be seen 1 - DOS
data long enough to be seen 2 - DOS
data long enough to be seen 3 - DOS
data long enough to be seen 4 - DOS
data long enough to be seen 5 - DOS
$ sed 's/Unix/Mac/g' test.unx | ule -m > test.mac
$ cat test.mac
$ ta long enough to be seen 5 - Mac
$ odx test.mac
0x0000: 0D 0D 64 61 74 61 20 6C 6F 6E 67 20 65 6E 6F 75 ..data long enou
0x0010: 67 68 20 74 6F 20 62 65 20 73 65 65 6E 20 31 20 gh to be seen 1
0x0020: 2D 20 4D 61 63 0D 0D 64 61 74 61 20 6C 6F 6E 67 - Mac..data long
0x0030: 20 65 6E 6F 75 67 68 20 74 6F 20 62 65 20 73 65 enough to be se
0x0040: 65 6E 20 32 20 2D 20 4D 61 63 0D 64 61 74 61 20 en 2 - Mac.data
0x0050: 6C 6F 6E 67 20 65 6E 6F 75 67 68 20 74 6F 20 62 long enough to b
0x0060: 65 20 73 65 65 6E 20 33 20 2D 20 4D 61 63 0D 64 e seen 3 - Mac.d
0x0070: 61 74 61 20 6C 6F 6E 67 20 65 6E 6F 75 67 68 20 ata long enough
0x0080: 74 6F 20 62 65 20 73 65 65 6E 20 34 20 2D 20 4D to be seen 4 - M
0x0090: 61 63 0D 0D 0D 0D 64 61 74 61 20 6C 6F 6E 67 20 ac....data long
0x00A0: 65 6E 6F 75 67 68 20 74 6F 20 62 65 20 73 65 65 enough to be see
0x00B0: 6E 20 35 20 2D 20 4D 61 63 0D 0D 0D n 5 - Mac...
0x00BC:
$ dupnl < test.unx
data long enough to be seen 1 - Unix
data long enough to be seen 2 - Unix
data long enough to be seen 3 - Unix
data long enough to be seen 4 - Unix
data long enough to be seen 5 - Unix
$ dupnl < test.dos
data long enough to be seen 1 - DOS
data long enough to be seen 2 - DOS
data long enough to be seen 3 - DOS
data long enough to be seen 4 - DOS
data long enough to be seen 5 - DOS
$ dupnl < test.mac
$ ta long enough to be seen 5 - Mac
$ dupnl < test.mac | odx
0x0000: 64 61 74 61 20 6C 6F 6E 67 20 65 6E 6F 75 67 68 data long enough
0x0010: 20 74 6F 20 62 65 20 73 65 65 6E 20 31 20 2D 20 to be seen 1 -
0x0020: 4D 61 63 0D 64 61 74 61 20 6C 6F 6E 67 20 65 6E Mac.data long en
0x0030: 6F 75 67 68 20 74 6F 20 62 65 20 73 65 65 6E 20 ough to be seen
0x0040: 32 20 2D 20 4D 61 63 0D 64 61 74 61 20 6C 6F 6E 2 - Mac.data lon
0x0050: 67 20 65 6E 6F 75 67 68 20 74 6F 20 62 65 20 73 g enough to be s
0x0060: 65 65 6E 20 33 20 2D 20 4D 61 63 0D 64 61 74 61 een 3 - Mac.data
0x0070: 20 6C 6F 6E 67 20 65 6E 6F 75 67 68 20 74 6F 20 long enough to
0x0080: 62 65 20 73 65 65 6E 20 34 20 2D 20 4D 61 63 0D be seen 4 - Mac.
0x0090: 64 61 74 61 20 6C 6F 6E 67 20 65 6E 6F 75 67 68 data long enough
0x00A0: 20 74 6F 20 62 65 20 73 65 65 6E 20 35 20 2D 20 to be seen 5 -
0x00B0: 4D 61 63 0D Mac.
0x00B4:
$
Usage: ule [-cdhmnsuzV] [file ...]
-c Check line endings (default)
-d Convert to DOS (CRLF) line endings
-h Print this help and exit
-m Convert to MAC (CR) line endings
-n Ensure line ending at end of file
-s Write output to standard output (default)
-u Convert to Unix (LF) line endings
-z Check for zero (null) bytes
-V Print version information and exit
if newline > 2
boolean firstNewlineFound = false