使用I / O重定向不会在一个空白行(C)中挤压多个空行

时间:2017-06-07 10:05:10

标签: c

我被要求在输入中将两个或多个连续的空行压缩为输出中的一个空白行。所以我必须使用Cygwin进行I / O或测试。 示例:./ Lab< test1.txt>的test2.txt

我的代码是:

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$APIresponse = curl_exec($ch);
curl_close($ch);
$res = json_decode($APIresponse, true);

但是我的test2.txt没有我想要的结果。我的逻辑/代码有什么问题吗?

2 个答案:

答案 0 :(得分:1)

剖析这个:

if(c == '\n') {
        nlines++;

nlines是否重置为零?

        if(nlines > 1){
            c = '\n';

第三个\n依次发生了什么? nlines > 1会是真的吗?想一想!

        }
}
putchar(c);

我不明白:无论如何,你无条件地输出你的角色,打败了检查它是否是换行符的全部目的。

正确的解决方案会在c为换行符时设置标记,而不输出任何内容。然后,当c不是换行符(else分支)时,如果设置了标志,则输出一个换行符并重置标志。我现在把代码写给你了:)

答案 1 :(得分:1)

你提供的代码太少,有趣的部分就是围绕你发布的代码循环......

你实际需要做的是跳过输出:

FILE* file = ...;
char c, prev = 0;
while((c = fgets(file)) != EOF)
{
    if(c != '\n' || prev != '\n')
        putchar(c);
    prev = c;
}

如果我们在另一个后面有一个空行,那么我们会遇到两个后续的换行符,因此cprev都等于'\n',这是我们不会的情况想要输出c(后续的换行符) - 而且相反的情况是两者中的任何一个都不等于'\n',如上所示 - 而只有你想要输出你的角色......

旁注:prev = 0 - 好吧,我需要将其初始化为新行,不管是's' - 当然,除非你想跳过一个初始的空行同样,你必须用'\n' ...

初始化它

修改,参考您修改后的代码: Edit2 (删除对代码的引用,因为它再次更改)

由于您的修改后的代码显示您不仅要压缩空白行,而且还要空白,您首先要考虑的是,您有两类空格,一方面是换行符,另一方面是空格。其他。所以你必须适当区分。

我建议现在使用某种状态机:

#define OTH  0
#define WS   1
#define NL1  2
#define NL2  3

int state = OTH;

while (( c= getchar()) != EOF )
{
    // first, the new lines:
    if(c == '\n')
    {
        if(state != NL2)
        {
            putchar('\n');
            state = state == NL1 ? NL2 : NL1;
        }
    }
    // then, any other whitespace
    else if(isspace(c))
    {
        if(state != WS)
        {
            putchar(' ');
            state = WS;
        }
    }
    // finally, all remaining characters
    else
    {
        putchar(c);
        state = OTH;
    }
}

首先区分当前角色自己的类(换行符,空格或其他),根据前一个字符的类进行第二次微分,该类定义当前状态。输出总是针对任何非空白字符或者如果只有两个后续空白字符,如果它们属于不同的类(换行有点具体,我需要两个状态,因为我们想留下一个空行,这意味着我们需要两个后续的换行符......)。

请注意:在上面的算法中,只有空格的行不作为空白行应用,因此它们不会被删除(但缩小为包含一个单独空格的行)。从您发布的代码中,我认为这是... ...

为了完整性:这是一个完全删除前导和尾随空格并将仅空白行计为空行的变体:

if(c == '\n')
{
    if(state != NL2)
    {
        putchar('\n');
        state = state == NL1 ? NL2 : NL1;
    }
}
else if(isspace(c))
{
    if(state == OTH)
        state = WS;
}
else
{
    if(state == WS)
    {
        putchar('');
    }
    putchar(c);
    state = OTH;
}

秘密:如果之前有非ws字符,则只输入空白状态,但在遇到下一个非空格之前不打印空格字符。

来到换行符 - 好吧,如果 是正常字符,我们要么处于状态OTH或WS,要么都不是两个NL状态。如果该行只有空格,则状态不会被修改,因此我们保持相应的NL状态(1或2)并相应地跳过该行......