“;如何修复&x2018;格式字符串不是字符串文字(可能不安全)’;C”中的错误;

“;如何修复&x2018;格式字符串不是字符串文字(可能不安全)’;C”中的错误;,c,cs50,C,Cs50,我正在做cs50,有一个关于函数的问题,我不能理解这两个代码之间的区别。为什么第一个代码会出错? 就在cs50沙箱上 我的代码(出错) #包括 #包括 int获取正int(字符串提示); 内部主(空) { int num=获取正整数(“高度:”); } int获取正整数(字符串提示) { int-num; 做 { num=get_int(提示); } 而(numC中的字符串文字:“这是字符串文字”的类型为(const char*) 但是,由于您将其作为参数传递给接受(string)变量的函数,

我正在做cs50,有一个关于函数的问题,我不能理解这两个代码之间的区别。为什么第一个代码会出错?

就在cs50沙箱上

我的代码(出错)

#包括
#包括
int获取正int(字符串提示);
内部主(空)
{
int num=获取正整数(“高度:”);
}
int获取正整数(字符串提示)
{
int-num;
做
{
num=get_int(提示);
}
而(numC中的字符串文字:“这是字符串文字”的类型为(const char*)

但是,由于您将其作为参数传递给接受(string)变量的函数,因此您的变量被隐式转换为一个字符串,该字符串似乎不是get_int()函数的有效参数

试试这个代码

#include <cs50.h>
#include <stdio.h>

int get_positive_int(const char* prompt);

int main(void)
{
    int num = get_positive_int("Height:");
}

int get_positive_int(const char* prompt)
{
    int num;
    do
    {
        num=get_int(prompt);
    }
    while(num<1);
    return num;
}
#包括
#包括
int获取正int(常量字符*提示);
内部主(空)
{
int num=获取正整数(“高度:”);
}
int获取正整数(常量字符*提示)
{
int-num;
做
{
num=get_int(提示);
}
而(numC中的字符串文字:“这是字符串文字”的类型为(const char*)

但是,由于您将其作为参数传递给接受(string)变量的函数,因此您的变量被隐式转换为一个字符串,该字符串似乎不是get_int()函数的有效参数

试试这个代码

#include <cs50.h>
#include <stdio.h>

int get_positive_int(const char* prompt);

int main(void)
{
    int num = get_positive_int("Height:");
}

int get_positive_int(const char* prompt)
{
    int num;
    do
    {
        num=get_int(prompt);
    }
    while(num<1);
    return num;
}
#包括
#包括
int获取正int(常量字符*提示);
内部主(空)
{
int num=获取正整数(“高度:”);
}
int获取正整数(常量字符*提示)
{
int-num;
做
{
num=get_int(提示);
}

而(num在第一个代码示例中,编译器抱怨在第15行传递给get#int()函数调用的第一个参数“不是字符串文字”。原因是中的get#int()定义:

C/C++标准的“格式”,通过该格式,我们可以要求编译器对源代码执行更多检查。在您的示例中,我们希望编译器对get_int()的第一个参数运行类型检查。为了运行类型检查,编译器希望get_int()的第一个参数是一个文本值,而不是一个变量

正确的代码示例包含预期的字符串文字,因此允许编译器运行类型检查并编译而不会出现问题:

n = get_int("Height: ");

在第一段代码中,示例编译器抱怨在第15行传递给get#int()函数调用的第一个参数“不是字符串文字”。原因是中的get#int()定义:

C/C++标准的“格式”,通过该格式,我们可以要求编译器对源代码执行更多检查。在您的示例中,我们希望编译器对get_int()的第一个参数运行类型检查。为了运行类型检查,编译器希望get_int()的第一个参数是一个文本值,而不是一个变量

正确的代码示例包含预期的字符串文字,因此允许编译器运行类型检查并编译而不会出现问题:

n = get_int("Height: ");

这就是为什么它不是一个默认警告。它并不总是有用的。在某些情况下,它确定了真正的问题,特别是如果程序用户(而不是程序员)可以控制格式字符串。在这种情况下,它不是一个重大问题(我认为它根本不是问题)。至于如何修复它-您必须用常量字符串替换变量,这对I18N/L10N来说是一件痛苦的事情(基本上不可能),对这些实用程序函数来说也是一件麻烦事。您可以尝试
get_int(“%s”,提示符)
。这就是为什么它不是一个默认警告。它并不总是有用的。在某些情况下,它肯定会发现真正的问题,特别是如果程序的用户(而不是程序员)可以控制格式字符串。在这种情况下,这不是一个重大问题(我认为这根本不是问题)。至于如何修复它-您必须用常量字符串替换变量,这对I18N/L10N来说是一件痛苦的事(基本上不可能),对这些实用程序函数来说也是一件麻烦事。您可以尝试
获取int(“%s”,提示符)
n = get_int("Height: ");