CS50 IDE: printf returns 额外字符

CS50 IDE: printf returns extra characters

我在使用 CS50 IDE 中的 printf 函数时遇到问题。当我使用 printf 打印出一个字符串(此代码中的盐)时,正在输出原始参数 (argv) 中不存在的额外字符。

下面贴出我的代码。任何帮助,将不胜感激。谢谢。

#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>

int main(int argc, string argv[])
{
    // ensuring that only 1 command-line argument is inputted
    if (argc != 2)
    {
        return 1;
    }
    char salt[2];
    for (int i = 0; i < 2; i++)
    {
        char c = argv[1][i];
        salt[i] = c;
    } 

    printf("the first 2 characters of the argument is %s\n", salt);

}

在你的情况下,salt 至少比 字符串 少一个元素,除非 argv[1] 只是一个元素,否则它不会包含空终止符。

您需要分配 space 来保存空终止符,并实际将其放在那里以便能够将 salt 用作 string,如预期的那样在 printf() 的情况下,用于 %s 转换说明符的参数。

否则,字符串相关的函数和操作,本质上依赖于一个空终止符来标记char数组的结束(即标记有效内存的结束,可以被访问),将尝试访问导致 undefined behavior 的有效内存。一旦你打了UB,什么都没有保证。

所以,考虑到您想使用

"....the first 2 characters of the argument....."

您需要使 salt 成为一个 3 元素的 char 数组,并确保 salt[2] 包含空终止符,例如 '[=19=]'.

您在 salt 中缺少字符串终止符。

计算机需要以某种方式知道您的字符串在内存中的结尾位置。它通过读取直到遇到 NUL 字节来实现,这是一个值为零的字节。

你的数组 salt 恰好有 2 个字节的 space,在它们之后,存在随机垃圾,恰好在你的数组之后的内存中。由于您没有字符串终止符,因此计算机也会读取这些垃圾,直到遇到 NUL 字节。

您需要做的就是在数组中包含这样一个字节,如下所示:

char salt[3] = {0};

这将使 salt 长一个字节,而 {0}{0, 0, 0} 的 shorthand,它将用所有零值初始化数组的内容。 (或者,您可以使用 char salt[3];,然后使用 salt[2] = 0; 手动将最后一个字节设置为零。)