Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.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_File - Fatal编程技术网

C 将文件中的多个新行替换为一行

C 将文件中的多个新行替换为一行,c,file,C,File,此函数用于在文本文件中搜索新行字符。当找到换行符时,它会增加新行< /代码>计数器,并且当有超过2个连续的空白新行时,它假设将所有空行压缩为一个空行。 在我的代码中,如果有两个新行,则假设它将它们去掉并压缩成一行,出于测试目的,我还让它在达到新行

此函数用于在文本文件中搜索新行字符。当找到换行符时,它会增加<代码>新行< /代码>计数器,并且当有超过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

示例代码解析的是:

1) 将连续的几个'\n'压缩为一个'\n'

2) 如果有,请去掉开头的“\n”

  input:   '\n\n\naa\nbb\n\ncc' 
  output:   aa'\n'    
            bb'\n' //notice, there is no blank line here
            cc
如果这是目标,那么您的代码逻辑是正确的

  • 通过定义
    newLine=1
    ,它将删除 输入文本

  • 当处理后仍有一个“\n”时,它将输出一个
    新行
    ,给出提示

回到问题本身,如果实际目的是将连续的空行压缩为一个空行(需要两个连续的“\n”,一个用于终止前一行,一个用于空行)

1) 让我们先确认输入和预期输出

输入文本:

预期输出文本:

2) 如果是如上所述的确切计划目标,则

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