gpt4 book ai didi

c - C中将空行压缩为一个空行

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

你好指的是同一个问题但是不同的代码。

Replacing multiple new lines in a file with just one

int main(void){

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

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

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

/*TABS*/
if(c == '\t'){
c = ' ';
}
/*SPACES*/
if (c ==' '){
if(nspace > 0){
continue;
}
else{
putchar(c);
nspace++;
nlines = 0;
}
}

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

我想将多个空行压缩成一个空行,但它似乎不起作用,在标准输出的 Cygwin 终端上,最后一行给了我额外的空行,尽管输入末尾没有空行.

例如
输入

Hello   Hi\n
\n
\n
Hey\t\tHola\n

期望的输出

Hello Hi\n
\n
Hey Hola\n

实际输出

Hello Hi\n
Hey Hola\n

请解释!

最佳答案

这是您的代码的一个变体。我删除了 format() 函数(这对我来说很不寻常,因为 SO 上的大多数程序都没有使用足够的函数)将它直接合并到 main() 中。该代码现在更加对称地处理空格和换行符,修复了 paddy 中也确定的双增量问题。的 answer .如果末尾还没有换行符,它也只会在末尾打印出一个换行符。这规范化了不以换行符结尾的文件。 nlines = 1; 的初始化处理文件开头的多个换行符——这已经做得很好了。

#include <stdio.h>

int main(void)
{
int c;
size_t nlines = 1;
size_t nspace = 0;

while ((c = getchar()) != EOF)
{
if (c == '\t')
c = ' ';
if (c == ' ')
{
if (nspace < 1)
{
putchar(c);
nspace++;
nlines = 0;
}
}
else if (c == '\n')
{
if (nlines < 2)
{
putchar(c);
nlines++;
nspace = 0;
}
}
else
{
putchar(c);
nspace = 0;
nlines = 0;
}
}
if (nlines == 0)
putchar('\n');
return 0;
}

我的测试使用了一些特定于 Bash 的符号。我的程序是 sb73:最后一个测试输入不包括最终换行符。输出使用 ⌴ 指示输出中的换行符:

$ echo $'Hello   Hi\n\n\nHey\t\tHola\n' | sb73
Hello Hi⌴

Hey Hola

$

和:

$ echo $'\n\nHello   Hi\n\n\n    Hey\t\tHola\n' | sb73

Hello Hi⌴

Hey Hola⌴

$

和:

$ printf '%s' $'\n\nHello   Hi\n\n\n    Hey\t\tHola' | sb73

Hello Hi⌴

Hey Hola⌴
$

处理 CRLF 行结尾

注释指出上面的代码在 Cygwin 终端上不起作用,合理的原因是被修改的数据有 CRLF 行结尾。有多种解决方法。一个是找到一种强制标准输入进入文本模式的方法。在文本模式下,CRLF 行结尾应映射到输入时的 Unix 样式 '\n'(仅限 NL 或 LF)结尾,而 Unix 样式行结尾应映射到输出时的 CRLF 行结尾.

或者,可以简单地忽略 CR 字符:

--- sb73.c  2017-06-08 22:04:28.000000000 -0700
+++ sb47.c 2017-06-08 22:40:24.000000000 -0700
@@ -19,6 +19,8 @@
nlines = 0;
}
}
+ else if (c == '\r')
+ continue; // Windows?
else if (c == '\n')
{
if (nlines < 2)

这是一个“统一差异”,在代码中显示了额外的两行。或者可以将 CR 后面没有跟随 LF 作为常规字符处理,而处理 CR 后面跟着 LF 作为换行符组合:

--- sb73.c  2017-06-08 22:04:28.000000000 -0700
+++ sb59.c 2017-06-08 22:42:43.000000000 -0700
@@ -19,6 +19,17 @@
nlines = 0;
}
}
+ else if (c == '\r')
+ {
+ if ((c = getchar()) == '\n')
+ {
+ ungetc(c, stdin);
+ continue;
+ }
+ putchar('\r');
+ nspace = 0;
+ nlines = 0;
+ }
else if (c == '\n')
{
if (nlines < 2)

可能有一种方法可以编写处理 CR 的状态机,但那样会更复杂。

我有一个 utod 程序可以将 Unix 风格的行结尾转换为 Windows 风格;我在管道中使用它来测试代码的新变体。

关于c - C中将空行压缩为一个空行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44449124/

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