C程序输出奇怪的字符

问题描述

尝试在 C 中打印反向输入:

#include <stdio.h>

#define MAX_SIZE 100
/* Reverses input */
void reverse(char string[],char reversed[]);

int main() {
    char input[MAX_SIZE],output[MAX_SIZE + 1];
    char c;
    int index = 0;

    while ((c = getchar()) != '\n')
    {
        input[index] = c;
        ++index;
    }

    reverse(input,output);
    printf("%s\n",output);

}

void reverse(char string[],char reversed[]) {  
    int rev;
    rev = 0;

    for (int str = MAX_SIZE - 1; str >= 0; --str) {
        if (string[str] != '\0') {
            reversed[rev] = string[str];
            ++rev;
        }
    }
}

但有这个奇怪的结果:

输入:

ABC

输出

?:? ????:???:?cba?

输入和输出数组都包含 \0,所以我猜有一些索引越界异常,但我找不到确切的位置。谢谢。

解决方法

对于原始字符串的长度,您不应该使用 MAX_SIZE,因为这是容器的总​​大小,而不是字符串的大小。

另一个问题是输入字符串不是空终止的,因此不可能知道它的长度,除非您跟踪从 stdin 读取的字符数并将其作为参数传递。>

修复这两个主要问题(以及其他一些小问题(评论))将使您的代码正常工作:

#include <stdio.h>
#include <string.h>

#define MAX_SIZE 100

void reverse(const char string[],char reversed[]);
int main()
{
    char input[MAX_SIZE],output[MAX_SIZE]; // no need for the extra character
    char c;
    int index = 0;

    while ((c = getchar()) != '\n' && index < MAX_SIZE - 1) // avoid buffer overflow
    {
        input[index] = c;
        ++index;
    }
    input[index] = '\0'; // null terminate the original string

    reverse(input,output);
    printf("%s\n",output);
}
void reverse(const char string[],char reversed[])
{
    int rev;
    rev = 0;

    // stop condition with the length of the string
    for (int str = strlen(string) - 1; str >= 0; --str)
    {
        reversed[rev] = string[str];
        ++rev;
    }
    reversed[rev] = '\0'; // null terminate the reversed string
}
,

对于初学者来说,不清楚为什么数组 inputMAX_SZIE 个元素

char input[MAX_SIZE],output[MAX_SIZE + 1];

而数组 outputMAX_SIZE + 1 个元素。

在这个循环之后(这是不安全的)

while ((c = getchar()) != '\n')
{
    input[index] = c;
    ++index;
}

数组 input 不包含字符串。

函数str内这个循环中变量revrese的初始值

for (int str = MAX_SIZE - 1; str >= 0; --str) {

没有意义,因为用户可以在数组中输入少于 MAX_SIZE - 1 个字符。

整个程序和函数reverse可以如下所示,如下面的演示程序所示。

#include <string.h>
#include <stdio.h>

#define MAX_SIZE 100

char * reverse( const char src[],char dsn[] )
{
    char *p = dsn + strlen( src );

    *p = '\0';

    while (p != dsn) *--p = *src++;

    return dsn;
}

int main( void )
{
    char input[MAX_SIZE],output[MAX_SIZE];

    size_t i = 0;

    for (int c; i + 1 < MAX_SIZE && ( c = getchar() ) != EOF && c != '\n'; ++i)
    {
        input[i] = c;
    }

    input[i] = '\0';

    puts( reverse( input,output ) );
}

如果输入例如文本

Hello World!

那么输出将是

!dlroW olleH

注意第一个函数参数应该有限定符const,因为传递的源字符串在函数内没有改变。该函数应遵循标准字符串函数的通用约定,并返回指向目标字符串的指针。那就是函数返回类型 void 没有多大意义。

当你处理字符串时,使用无符号类型 size_t 的对象而不是有符号类型 int 作为索引。类型 size_t 是函数 strlen 或运算符 sizeof 的返回值的类型。