gpt4 book ai didi

c - 使用 I/O 重定向不会将多个空行压缩到一个空行中 (C)

转载 作者:太空宇宙 更新时间:2023-11-04 08:03:27 25 4
gpt4 key购买 nike

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

我的代码是:

   int main(void){

format();
printf("\n");
return 0;
}


void format(){
int c;
size_t nlines = 1;
size_t nspace = 0;
int spaceCheck = ' ';

while (( c= getchar()) != EOF ){

/*TABS*/
if(c == '\t'){
c = ' ';
}
/*SPACES*/
if (c ==' '){/*changed from isspace(c) to c==' ' because isspace is true for spaces/tabs/newlines*/
/* while (isspace(c = getchar())); it counts while there is space we will put one space only */
if(nspace > 0){
continue;
}
else{
putchar(c);
nspace++;
nlines = 0;
}

}


/*NEW LINE*/
else if(c == '\n'){
if(nlines >0){
continue;
}
else{
putchar(c);
nlines++;
nspace = 0;
}

}


else{
putchar(c);
nspace = 0;
nlines = 0;

}







}

}

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

最佳答案

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

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

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 – 好吧,我需要将它初始化为不同于换行符的任何内容,也可能是 的' – 除非,当然,你也想跳过一个初始的空行,那么你必须用 '\n'...

初始化它

Edit,引用您修改后的代码: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)并相应地跳过该行...

关于c - 使用 I/O 重定向不会将多个空行压缩到一个空行中 (C),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44409576/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com