har*_*ski 1 c kernighan-and-ritchie
我正在通过 Kernighan & Ritchie 进行工作,并且必须练习 1.9。事实上,我编写了一些似乎可以解决这个练习的代码,并且我已经在 Windows(使用 Git Bash 和 gcc)和 Termux(使用 clang)上测试了它,方法是在一行中输入可变数量的空格,例如 ,echo " one two three"以及预期的输出出来即 one two three。
我通过反复试验找到了解决方案,尽管它与 Lvictor 在clc wiki上提供的解决方案相同。
我自己写的代码是:
#include <stdio.h>
/* Write a program to copy its input to its output, replacing each string of one or more blanks by a single blank. */
int main () {
int c;
while ((c = getchar()) != EOF) {
if (c == ' ') {
while ((c = getchar()) == ' ' ) {
}
putchar (' ');
}
putchar (c);
}
}
Run Code Online (Sandbox Code Playgroud)
我感到困惑的是为什么我需要这putchar (' ');条线。' '我不明白为什么程序退出if语句后c的值不是。最初我没有这一行,但令我惊讶的是,程序从输入中删除了所有空格。
由于我是一个初级C程序员,也许我对变量值的范围有些不理解,尽管在我看来,如果c的值是在' 'if语句开始时,并且如果是' '在第二个while中循环,当两者都退出时也应该是这样' ',但情况似乎并非如此。
我在 Google 上搜索了 K&R 练习 1.9,这就是我找到上面 wiki 的方式,并在 Stack Overflow 上查看了有关此练习的其他问题。
这两个实例getchar()使得正确处理 EOF 变得困难。
下面是一个可能更容易理解的替代方案:
#include <stdio.h>
int main( void ) {
int c;
int SPfound = 0;
while( ( c = getchar() ) != EOF ) // Note single "entry point" for data
if( c == ' ' ) // swallow and flag one or more contiguous SP's
SPfound = 1;
else {
if( SPfound ) // if any SP's, output a single one.
putchar( ' ' );
putchar( c ); // output the non-SP character.
SPfound = 0;
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,这将“修剪”在 EOF 之前获取的所有尾随空格。您可以考虑是否希望程序添加单个尾随 SP 来表示这些。
编辑:
不高兴离开它,这是另一个使用更少代码的版本。
#include <stdio.h>
int main( void ) {
for( int c, prev = 0; ( c = getchar() ) != EOF; prev = c )
if( !( c == ' ' && prev == ' ' ) ) // output when NOT consecutive SP's
putchar( c );
}
Run Code Online (Sandbox Code Playgroud)
这会输出遇到的任何 SP 系列中的第一个,但会抑制第二个、第三个……