为什么即使我定义了_CRT_SECURE_NO_WARNINGS,编译器仍然警告我使用了不安全的strtok?

6
我正在使用Visual Studio Express 2012 for Windows Desktop进行开发。
我经常会遇到错误。
Error C4996: 'strtok': This function or variable may be unsafe.
  Consider using strtok_s instead.
  To disable deprecation, use _CRT_SECURE_NO_WARNINGS.
  See online help for details.

当我尝试构建以下内容时:
#include "stdafx.h"
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
using namespace std;
int main() {
    char the_string[81], *p;
    cout << "Input a string to parse: ";
    cin.getline(the_string, 81);
    p = strtok(the_string, ",");
    while (p != NULL) {
        cout << p << endl;
        p = strtok(NULL, ",");
    }
    system("PAUSE");
    return 0;
}

即使我定义了_CRT_SECURE_NO_WARNINGS,为什么还会出现此错误,如何解决?


没有任何问题和意义。为什么不直接使用 strtok_s?有什么问题吗? - Blacktempel
1
你的 #define 语句应该在任何情况下都要 先于 #include "stdafx.h",或者放到项目属性的 C++/预处理器定义中。 - Roger Rowland
解决方案是:1)阅读在线帮助中的详细信息,2)使用建议的strtok_s - 或者使用C++函数而不是C。不要关闭警告。 - molbdnilo
@Blacktempel 因为 strtok_s 是专有库扩展,因此不具备可移植性。 - ComicSansMS
4个回答

7

您的 #define 无法正常工作,因为您预编译的头文件 (stdafx.h) 内容的原因。它的模板应该像这样:

#pragma once
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>

问题出在最后两个 #includes 上,这些 .h 文件已经包含了 string.h。因此你的 #define 命令已经太晚了。

解决方法之一是将宏定义放入编译器设置中,另一个简单的方法是将 #define 放到 stdafx.h 文件中。修改后如下:

#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>

6

这可能是一个旧帖子,但最近我也遇到了类似的问题。 我进入项目选项 -> C/C++ -> 预处理器 -> 添加_CRT_SECURE_NO_WARNINGS到预处理器定义列表中。 这样你就不必在每个文件中都写它。


2
请尝试以下操作。
#pragma warning (disable : 4996)

注意错误代码为 C4996。

-1

看起来您开启了一个编译器选项,强制编译器将所有警告视为错误。要么关闭此选项,要么确实使用宏 _CRT_SECURE_NO_WARNINGS。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接