我正在做Brian W. Kernighan和Dennis M. Ritchie的">C编程语言"第2版练习。
练习1.9让我感到困惑。所以这里是:
"编写一个程序将其输入复制到输出,将每个字符串替换为一个空格"。
我对此感到困惑。我在这里发布我的问题,因为其他学习者没有像我想做的那样做这个练习。在这里,使用 -
表示空白:
Input: ----hello
Output: -hello
但我想要这个:
Input: ----hello
Output: ----hello
Input: ----
Output: -
所以这是我的程序:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int character; /* input character */
int non_blank = 0; /* is any non blank character */
while ((character = getchar()) != EOF) {
if (character != 'n') {
putchar(character);
if (character != ' ') {
non_blank = 1;
}
}
else {
if (non_blank == 0 ) {
putchar('b'); /* go to previous line (blablan|cursor|) (blabla|cursor|n) */
putchar('r'); /* carriage return */
putchar(' '); /* put one space */
putchar(' '); /* and put the end of line */
}
non_blank = 0;
}
}
return EXIT_SUCCESS;
}
但空间不会被擦除。
Input: ------|n
Output: -|-----
这是我对转义序列的实验:
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("bbbbbbbbbbbbbbb");
putchar('b'); /* jump to previous line */
putchar('r');
putchar('b');
putchar(' ');
return EXIT_SUCCESS;
}
|
是一个游标。
Output: b|
但是当我添加换行符时,它不起作用。如何使其与换行符一起使用?
代码的问题在于,一旦处理字符,就会打印字符,一旦检测到必须将它们压缩到一个空格,就会尝试擦除它们。
您的方法是有效的,但您必须首先知道b
只会使光标返回一个空格(不擦除(,因此正确的方法是发出b b
(一个退格,一个覆盖字符的空间和另一个退格键将光标留在正确的位置(
另一种方法是等待打印任何内容,直到我们知道该行是以非空字符串结尾还是仅以n
字符结束。
以下代码对空白字符进行计数,并管理两种状态来应对这种情况。 当然,您将能够遵循代码,我试图用注释来记录它。
#include <stdio.h>
int main()
{
int c;
int state = 0;
int nblanks = 0;
/* read chars up to EOF */
while((c = getchar()) != EOF) {
switch (state) {
case 0: /* no nonblank character read */
switch (c) {
/* accumulate number of blanks to be printed in case
* we see a nonblank char before n */
case ' ': nblanks++; break;
/* in this case we have seen nblanks before a n, so
* we have to print only one blank and n */
case 'n':
puts(" "); /* just one space */
nblanks = 0; /* reset counter */
break;
/* nonblank char */
default:
/* print all the blanks up to here */
printf("%*s%c", nblanks, "", c);
state = 1; /* switch state */
break;
} /* switch */
break;
/* we have read at least a nonblank char, so we must
* echo the line until the end. */
case 1:
if (c == 'n') {
state = 0;
nblanks = 0;
} /* if */
putchar(c);
break;
} /* switch */
} /* while */
} /* main */
它与K&R第二版完全兼容,所以你只需要编译它并运行。
也许最难遵循的陈述是中间的printf()
线。 星号*
允许我使用 printf 参数指定字段的宽度,传递空字符串""
允许我打印包含nblanks
空格的字符串。 最后的%c
格式是打印刚刚读取的非空白字符。 这导致了一个紧凑而高效的代码。
最后,你有一些错误的想法:
-
b
只返回终端中的一个字符(一个字符,而不是一行(。 我不仅在打印到终端或打印机时工作。 它不适用于文件(文件将获得退格符作为普通字符( -
r
使光标转到第一个显示列。 这仅适用于屏幕和打印机。 它在文件中不起作用,它作为普通字符包含在文件中。 -