未定义的输出(K&R 1.19)

Undefined output (K&R 1.19)

我正在尝试找出 K&R 的练习 1.19。

Write a function reverse(s) that reverses the characte string s. Use it to write a program that reverses its input a line at a time

这是我的代码

#include <stdlib.h>
#include <stdio.h>
#define MAX 150

void reverse(char s[]);

int main()
{
    int c, i;
    char string[MAX];

    i=0;
    while((c=getchar())!= EOF){
       while((c=getchar()) != '\n'){
            string[i] = c;
            i++;
       }
       reverse(string);
    }
    return 0;
}
void reverse(char s[]){
   int i, j;
   for(i=0; i<MAX-1; i++){
       if(s[i] == '\n')
          break;
   }
   for(j=i;j>=0;j--)
     printf("%c", s[j]);
   printf("\n");

}

问题是我有一个未定义的输出,就像这样

我想弄清楚,但对我来说没有意义。 预先感谢您的帮助。

尝试替换

while((c=getchar())!= EOF){
   while((c=getchar()) != '\n'){
        string[i] = c;
        i++;
   }

与:

while(((c=getchar())!= EOF) && (c != '\n')){
        string[i] = c;
        i++;
        string[i] = '[=11=]'
   }

我建议您不要使用这些循环 -

while((c=getchar())!= EOF){
   while((c=getchar()) != '\n'){

试试这个 -

 while((c=getchar()) != '\n' && c!=EOF){

在这个循环之后调用函数之前 -

string[i]='[=12=]';   // append '[=12=]' 

并在函数 reverse 中检查 '\n' 而不是检查 '[=16=]' -

for(i=0; s[i]!='[=13=]'; i++){      //you use it to get length of string
}
 /* Or better to get length use strlen() from <string.h>   */  

您的代码中存在几个问题。

首先,您 "swallow" 检查 EOF 的第一个字符;第一个写入数组的实际上是第二个(如果您向缓冲区键入 string^ it would copytring`)。

然后你反转整个缓冲区(150 个字符)而不考虑包含的字符串的长度。您看到的垃圾只是您也反转的缓冲区的 "rest" 。注意 "garbage" 的最后一个字符是 gnirt,这是 tring 颠倒过来的。

然后还要注意使用 [=13=] 正确的字符串终止。

#include <stdio.h>

#define MAX_ARRAY_SIZE 50

void Reverse(char string[]);

void Reverse(char string[])
{
    int stringSize = 0;

我使用 while 循环遍历字符串数组并计算其长度

    while (string[stringSize] != '[=11=]')
    {
        stringSize++;
    }

    int  i = 0;

我减少了 stringSize,所以当它最后打印出来时它不包含 NULL 终止符 ('\0')

    stringSize -= 1;

    for (i = stringSize; i >= 0; i--)
    {
        printf("%c", string[i]);
    }

    printf("\n");
}

int main(int argc, char *argv[])
{
    int i = 0;
    int c = 0;

    char string[MAX_ARRAY_SIZE];

检查getchar是否为EOF或c是否为换行符('\n')

    while ((c = getchar()) != EOF && c != '\n')
    {
        string[i] = c;
        i++;
    }

将字符串[i]设置为一个空行字符,这样它就不会仅反向打印出包含字符串的部分

    string[i] = '[=14=]';

    Reverse(string);

    return 0;
}