如何解决C:从char数组打印会产生错误的字符
K。N. King的 C编程:现代方法第二版的解决方案,第8章,编程项目14,产生正确和错误的不同输出。示例如下所示:
Reversal of sentence: you can't swallow a cage can you?
Reversal of sentence: you can't swallow a cage can you�(�?
Reversal of sentence: you can't swallow a cage can you��x�?
Reversal of sentence: you can't swallow a cage can you�Ց�?
如示例输入所示,正确的输出应为:
Enter a sentence: you can cage a swallow can't you?
Reversal of sentence: you can't swallow a cage can you?
我自己的解决方案和以下解决方案(由Github用户@williamgherman提供;为了便于阅读而稍加修改)都会产生不同的输出。
#include <stdio.h>
int main(void)
{
char ch,terminator,sentence[100] = {0};
int i = 0,j;
printf("Enter a sentence: ");
for (i = 0; (ch = getchar()) != '\n' && i < 100; i++) {
if (ch == '.' || ch == '!' || ch == '?') {
terminator = ch;
break;
}
sentence[i] = ch;
}
printf("Reversal of sentence: ");
while (i >= 0) {
while (sentence[--i] != ' ' && i != 0)
;
j = i == 0 ? 0 : i + 1;
while (sentence[j] != ' ' && sentence[j] != '\0')
putchar(sentence[j++]);
if (i > 0)
putchar(' ');
}
printf("%c\n",terminator);
return 0;
}
尽管仔细检查了代码,并完成了纸上的示例输入,但我仍找不到答案。
代码为什么会产生这些不同的输出(正确与错误)?产生错误字符的原因是什么?
解决方法
最有可能的问题是while
循环的退出条件,该循环用于反向打印句子
while (i >= 0) {
while (sentence[--i] != ' ' && i != 0) ;
....
考虑代码要打印第一个单词(i = 3)的情况:
- 第二次将i一直递减为0
- 然后代码将显示单词'you'(位置0到2,包括0和2)
- 此时i = 0,第一个仍然为真
- 第二个while会将i减至-1,并将继续将其减至-2,-3,直到找到一个空格。
- 该代码将打印索引为-1,-2,-3的单词,并基于这些未定义的值打印字符串。
是的,如上面答案中所述,问题在此块内
it (`Testing Component`,() => {
render(<BrowserRouter><TestComponent /></BrowserRouter>
expect(screen.getAllBy('li')).toBeInTheDocument();
});
您应该将while (i >= 0) {
while (sentence[--i] != ' ' && i != 0) ;
....
部分更改为i != 0
,这应该可以解决问题
问题是我递减i >= 0
发生在之前 sentence[--i]
,因此可以想象从i = 0开始的while循环-这意味着i != 0
将(可能)不是sentence[i - 1]
,而我将不等于零。
对于初学者来说,该程序具有未定义的行为,因为未初始化变量terminator
。用户可以按Enter键,而无需提供以下字符之一:".!?"
for (i = 0; (ch = getchar()) != '\n' && i < 100; i++) {
^^^^^^^
在这种情况下,此语句
printf("%c\n",terminator);
将输出一个不确定的值。
此外,用户可以按相应的按键组合来中断循环,但循环不会处理这种情况。
如果用户在循环的最开始就按下Enter键,则i
将等于0
,在这种情况下,是内部while循环
while (i >= 0) {
while (sentence[--i] != ' ' && i != 0)
^^^
;
将调用未定义的行为。
此外,在结束字符(".!?"
)之前,句子可以包含空格。因此这个循环
while (sentence[--i] != ' ' && i != 0)
;
j = i == 0 ? 0 : i + 1;
再次将错误地终止。即j等于i + 1,其中存储了零个字符(前提是用户没有输入数组句子的所有100个元素)。
除此之外,该程序不会输出单词之间存在的空格数。它只会尝试输出一个空格
putchar(' ');
请考虑到用户可以输入例如制表符'\t'
而不是空格字符' '
。
下面显示了如何编写程序。
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int main(void)
{
const char *punctuation = ".?!";
enum { N = 100 };
char s[N] = "";
char terminator = '\0';
printf( "Enter a sentence: " );
size_t n = 0;
for ( int c; n < N && ( c = getchar() ) != EOF && c != '\n'; n++ )
{
if ( strchr( punctuation,c ) )
{
terminator = c;
break;
}
s[n] = c;
}
printf( "Reversal of sentence: " );
putchar( '\"' );
size_t i = 0;
while ( i != n && isblank( ( unsigned char )s[i] ) ) putchar( s[i++] );
for ( size_t j = n; i != n; )
{
while ( i != n && !isblank( ( unsigned char )s[i] ) ) i++;
while ( isblank( ( unsigned char )s[j-1] ) ) j--;
size_t k = j;
while ( j != 0 && !isblank( ( unsigned char )s[j-1] ) ) j--;
for ( size_t l = j; l != k; l++ ) putchar( s[l] );
while ( i != n && isblank( ( unsigned char )s[i] ) ) putchar( s[i++] );
}
if ( terminator ) putchar( terminator );
putchar( '\"' );
return 0;
}
程序输出看起来像
Enter a sentence: you can cage a swallow can't you?
Reversal of sentence: "you can't swallow a cage can you?"
如您所见,程序保留了所输入句子中包含的所有空格。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。