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

“How to fix ‘format string is not a string literal (potentially insecure)’ error in C”

我在做cs50,请教一个关于功能的问题,我无法理解这两个之间的区别codes.why第一个出错了?

就在 CS50 沙盒上

我的代码(出错)

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

int get_positive_int(string prompt);

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

int get_positive_int(string prompt)
{
    int num;
    do
    {
        num=get_int(prompt);
    }
    while(num<1);
    return num;
}

正确的代码

#include <cs50.h>
#include <stdio.h>
int get_positive_int(void);
int main(void)
{
    int i = get_positive_int();
}
// Prompt user for positive integer
int get_positive_int(void)
{
    int n;
    do
    {
        n = get_int("Height: ");
    }
    while (n < 1);
    return n;
}

C 中的字符串文字:"this is a string literal" 是 (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;
}

在第一个代码示例中,编译器抱怨 "not a string literal" 第一个参数传递给第 15 行的 get_int() 函数调用。原因是get_int()在cs50.h with a special attribute:

中的定义
int get_int(const char *format, ...) __attribute__((format(printf, 1, 2)));

"format" attribute is a GNU extension 到 C/C++ 标准,我们可以根据该标准要求编译器对我们的源代码执行更多检查。在您的示例中,我们希望编译器针对 get_int() 的第一个参数进行 运行 类型检查。为了 运行 类型检查,编译器期望文字值而不是变量作为 get_int() 的第一个参数。

正确的代码示例包含预期的字符串文字,因此允许编译器 运行 进行类型检查并顺利编译:

n = get_int("Height: ");