为什么这段代码没有正确压缩空格?

我正在研究K&R的The C Programming Language 。 我正在进行一项练习,其中写着“编写一个程序,将所有输入复制到其输出中,用一个空格替换每个字符串的一个或多个空格。”

我相信我已经解决了。 有些。 当第一次使用a.out运行程序时,我可以输入一个包含多个空格的数字,只需一个空格即可返回。 但是,当我转到下一行再试一次时,它将返回没有空格的数字。 另外,如果我输入一串字母如“ 33 33 33 ”,它只会为整行留下一个空格。 变成“ 33 3333 ”。

我知道我可以只谷歌练习本身的答案,但我认为这不会帮助我了解为什么我的代码表现如此。 任何帮助将非常感激。

 main() { int c, nl, upper; nl = 0; upper = 2; while( ( c = getchar() ) != EOF ) { if( c == ' ' ) { ++nl; if( nl >= upper ) { --c; --nl; } } putchar(c); } } 

不错的尝试。 但是你犯了一些错误。

当遇到空格以外的字符时,您没有将计数器设置为初始值。 因此,如果您的输入在非空白字符(例如33 33 33之间有多个空格,则将打印第一个空白区域,并跳过其他空白区域。 所以输出将是33 3333

你必须明白char数据类型只存储单个字符和ASCII编码。 在char上应用算术运算时,它只是更改字符值。 因此,当您减少char变量时,它引用另一个字符。 所以最终它打印垃圾值。

试试这个。

 while ((c = getchar()) != EOF){ if (c == ' '){ ++nl; if (nl >= upper){ continue; } } else{ nl=0; } putchar(c); } 

逻辑很简单……
如果有多个空格,请放置第一个空格并跳过其他空格。

 int main() { int c, nl; nl = 0; while ((c = getchar()) != EOF) { if (c == ' ') { nl ++; } else { nl = 0; } if (nl <= 1) { putchar(c); } } return 0; } 

你发布的解决方案比它需要的更复杂 – 你也执行一些对我来说毫无意义的操作,比如c -= ' '

我认为你应该在编程中使用任何特定语言来设计算法和问题解决。 考虑一下如何只用输入字符串和一块方形纸和一支铅笔来自己做。

在伪代码中,最小解决方案如下:

 1. Read character C from input (if there is no input, end program) 2. If character is a space character: 2.1. Was the last printed character a space character too? If so, don't print anything and loop back to step 1. 3. Else, print character C and loop back to step 1. 

在C中,这可以写得最低(在C11中):

 int main( void ) { bool last_char_was_space = false; int c; while( ( c = getchar() ) != EOF ) { if( last_char_was_space ) { if( c == ' ' ) continue; // don't print anything else { putchar( c ); last_char_was_space = false; } } else { putchar( c ); if( c == ' ' ) { last_char_was_space = true; } } } return 0; } 

这个程序是“有限状态机”的一个简单例子,它是一个有状态算法的例子,也是正则表达式和其他类型解析器之类的基础构建块。 如果您想编写一个能够以最高性能和最少内存使用量快速处理数据的程序,那么这是一项必不可少的技巧。