c++ - 我的程序在不同的机器上给出不同的输出..!

标签 c++ c string concatenation

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


int main()
{
    char left[4];
    for(int i=0; i<4; i++)
    {
        left[i]='0';
    }
    char str[10];
    gets(str);
    strcat(left,str);
    puts(left);
    return 0;
}

对于任何输入,它都应该将 0000 与该字符串连接起来,但在一台电脑上,它在“0000”和输入字符串之间显示一个菱形符号...!

最佳答案

您将可能的九个(或更多,gets 没有边界检查)字符串附加到三个字符的字符串(包含四个字符且没有字符串终止符)。根本没有字符串终止。因此,当您使用 puts 进行打印时,它将继续打印,直到找到一个字符串终止字符,该字符可能在内存中任何地方。简而言之,这是一个缓冲区溢出的教科书示例,缓冲区溢出通常会导致未定义的行为,这就是您所看到的。

在 C 和 C++ 中,所有 C 风格的字符串都必须终止。它们以特殊字符终止:'\0'(或纯 ASCII 零)。您还需要在 strcat 调用中为目标字符串提供足够的空间。


正确的工作程序:

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

int main(void)
{
    /* Size is 4 + 10 + 1, the last +1 for the string terminator */
    char left[15] = "0000";
    /* The initialization above sets the four first characters to '0'
     * and properly terminates it by adding the (invisible) '\0' terminator
     * which is included in the literal string.
     */

    /* Space for ten characters, plus terminator */
    char str[11];

    /* Read string from user, with bounds-checking.
     * Also check that something was truly read, as `fgets` returns
     * `NULL` on error or other failure to read.
     */
    if (fgets(str, sizeof(str), stdin) == NULL)
    {
        /* There might be an error */
        if (ferror(stdin))
            printf("Error reading input: %s\n", strerror(errno));
        return 1;
    }

    /* Unfortunately `fgets` may leave the newline in the input string
     * so we have to remove it.
     * This is done by changing the newline to the string terminator.
     *
     * First check that the newline really is there though. This is done
     * by first making sure there is something in the string (using `strlen`)
     * and then to check if the last character is a newline. The use of `-1`
     * is because strings like arrays starts their indexing at zero.
     */
    if (strlen(str) > 0 && str[strlen(str) - 1] == '\n')
        str[strlen(str) - 1] = '\0';

    /* Here we know that `left` is currently four characters, and that `str` 
     * is at most ten characters (not including zero terminaton). Since the
     * total length allocated for `left` is 15, we know that there is enough
     * space in `left` to have `str` added to it.
     */
    strcat(left, str);

    /* Print the string */
    printf("%s\n", left);

    return 0;
}

关于c++ - 我的程序在不同的机器上给出不同的输出..!,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20613081/

相关文章:

python - 需要更优雅的解决方案来均匀字符串长度

c++ - OpenGL 3.1 上下文创建后的 GL_INVALID_ENUM/GL_INVALID_OPERATION

c++从文件中一个一个地获取值

c++ - 使用 C++ 和修改基类的私有(private)/保护属性

c - 关于c中的read系统调用

C 编译程序崩溃

c - 为 2 个不同的程序定义相同的管道

python - 确保用户在使用 BMI 分析器时只输入整数

c++ - 使用 EvtSetChannelConfigProperty() 函数时出现访问冲突错误

python - 如何将字符串拆分为字符并将每个字符分配给单独的变量