CS50 IDE:printf返回额外的字符

时间:2017-03-16 06:58:23

标签: c string cs50

我在CS50 IDE中遇到printf功能问题。当我使用printf打印出一个字符串(此代码中的salt)时,正在输出原始参数(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);

}

2 个答案:

答案 0 :(得分:2)

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

计算机需要知道你的字符串在内存中的结束位置。它通过读取直到遇到NUL字节为止,这是一个值为零的字节。

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

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

char salt[3] = {0};

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

答案 1 :(得分:0)

在您的情况下,salt至少是一个不属于字符串的元素,除非argv[1]只是一个元素,它不包含空终止符

您需要分配空间来容纳空终止符,并实际将其放在那里以便能够将salt用作字符串,正如%s的参数所期望的那样printf()的转换说明符。

否则,字符串相关的函数和操作,基本上依赖于将有一个空终止符来标记char数组的结尾(即标记可以访问的有效内存的结尾)这一事实),将尝试访问导致undefined behavior的有效内存。一旦你击中UB,没有任何保证。

所以,考虑到你想要使用

的事实
  

“......论证的前两个字符.....”

您需要将salt设为3个元素char数组,并确保salt[2]包含空终结符,例如'\0'