CS50 IDE:printf返回额外字符
我对CS50 IDE中的printf函数有问题。当我使用printf打印字符串(在这段代码中是salt)时,会输出原始参数(argv)中不存在的额外字符 下面是我的代码。任何帮助都将不胜感激。多谢各位CS50 IDE:printf返回额外字符,c,string,cs50,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, str
#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);
}
#包括
#包括
#包括
#包括
#包括
int main(int argc,字符串argv[])
{
//确保只输入1个命令行参数
如果(argc!=2)
{
返回1;
}
焦盐[2];
对于(int i=0;i<2;i++)
{
字符c=argv[1][i];
盐[i]=c;
}
printf(“参数的前两个字符是%s\n”,salt);
}
在您的例子中,salt
至少比字符串少一个元素,除非argv[1]
只是一个元素,否则它不包含空终止符
您需要分配空间来容纳空终止符,并实际放置一个空终止符,以便能够使用salt
作为字符串,这与%s
转换说明符的参数在printf()情况下的预期一样
否则,与字符串相关的函数和操作(本质上依赖于将有一个空终止符来标记char
数组的结束(即,标记可访问的有效内存的结束))将尝试访问超出导致错误的有效内存。一旦你击中了UB,什么都不能保证
因此,考虑到您想要使用
“…参数的前2个字符…”
您需要将salt
设置为3元素char
数组,并确保salt[2]
包含空终止符,如'\0'
在您的情况下,salt
至少比字符串少一个元素,除非argv[1]
仅包含一个元素,否则它不包含空终止符
您需要分配空间来容纳空终止符,并实际放置一个空终止符,以便能够使用salt
作为字符串,这与%s
转换说明符的参数在printf()情况下的预期一样
否则,与字符串相关的函数和操作(本质上依赖于将有一个空终止符来标记char
数组的结束(即,标记可访问的有效内存的结束))将尝试访问超出导致错误的有效内存。一旦你击中了UB,什么都不能保证
因此,考虑到您想要使用
“…参数的前2个字符…”
您需要将salt
设置为3元素char
数组,并确保salt[2]
包含空终止符,如'\0'
您在salt
中缺少字符串终止符
不知何故,计算机需要知道字符串在内存中的结束位置。它通过读取直到遇到NUL字节(值为零的字节)来执行此操作
您的数组salt
正好有2个字节的空间,在它们之后,随机垃圾就存在了,它恰好是数组之后内存中的下一个垃圾。由于没有字符串终止符,计算机也将读取此垃圾,直到遇到NUL字节
您只需在数组中包含这样一个字节,如下所示:
char salt[3] = {0};
这将使salt
长一个字节,而{0}
是{0,0,0}
的缩写,它将用全零初始化数组的内容。(或者,您可以使用char salt[3];
,然后使用salt[2]=0;
手动将最后一个字节设置为零)您在salt
中缺少字符串终止符
不知何故,计算机需要知道字符串在内存中的结束位置。它通过读取直到遇到NUL字节(值为零的字节)来执行此操作
您的数组salt
正好有2个字节的空间,在它们之后,随机垃圾就存在了,它恰好是数组之后内存中的下一个垃圾。由于没有字符串终止符,计算机也将读取此垃圾,直到遇到NUL字节
您只需在数组中包含这样一个字节,如下所示:
char salt[3] = {0};
这将使salt
长一个字节,而{0}
是{0,0,0}
的缩写,它将用全零初始化数组的内容。(或者,您可以使用char-salt[3];
然后使用salt[2]=0;
手动将最后一个字节设置为零)C字符串必须以null结尾,但您的字符串不是。显示原始参数(argv)。printf(“参数的前两个字符是%s\n”,salt)
-->printf(“参数的前两个字符是%.2s\n”,salt)代码>C字符串必须以null结尾,但您的字符串不是。请显示原始参数(argv)。printf(“参数的前两个字符是%s\n”,salt)
-->printf(“参数的前两个字符是%.2s\n”,salt)代码>谢谢你的回复。简单的问题只是为了清楚的理解:为什么在初始化char salt[3]={0}之后我要执行printf(%s\n,salt)
编译器将理解salt[2]
中的0
不是字符“0”,而是字符串的空终止符?因为字符0
将在此上下文中写入'0'
,该值等于48
。尝试chartest[6]={'1',0',49,48,1,0};sprintf(“%s\n”,test)代码>以了解我的意思。(提示:笑脸的值为1
)。明白了,非常感谢。然而,在那个示例中,您的意思是printf(“%s\n”,test)
,而不是sprintf
,对吗?如果我错了,请纠正我:sprintf
需要为其分配一个缓冲区,在该示例中没有分配缓冲区。