- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我看到这 3 个函数都与打开文件有关。
open :
This POSIX function is deprecated. Use the ISO C++ conformant _open instead.
_open :
Opens a file. These functions are deprecated because more-secure versions are available; see _sopen_s, _wsopen_s.
fopen :
Opens a file. More-secure versions of these functions that perform additional parameter validation and return error codes are available; see fopen_s, _wfopen_s.
那么,为什么是三个呢?什么时候使用哪个?我认为 POSIX 很好,但为什么 MSDN 说 open
的 POSIX 版本已弃用?是否有任何与前导下划线相关的命名约定,以便我可以根据其第一眼选择正确的函数?
当我查看 ACPICA code 时,我看到下面的代码:_XXX
版本似乎可以禁用一些MS语言扩展,这些扩展到底是什么?
/*
* Map low I/O functions for MS. This allows us to disable MS language
* extensions for maximum portability.
*/
#define open _open
#define read _read
#define write _write
#define close _close
#define stat _stat
#define fstat _fstat
#define mkdir _mkdir
#define snprintf _snprintf
#if _MSC_VER <= 1200 /* Versions below VC++ 6 */
#define vsnprintf _vsnprintf
#endif
#define O_RDONLY _O_RDONLY
#define O_BINARY _O_BINARY
#define O_CREAT _O_CREAT
#define O_WRONLY _O_WRONLY
#define O_TRUNC _O_TRUNC
#define S_IREAD _S_IREAD
#define S_IWRITE _S_IWRITE
#define S_IFDIR _S_IFDIR
似乎单下划线前缀 _XXX
是 Microsoft 的惯例。如_DEBUG , _CrtSetDbgFlag ,以及前面提到的_open .一些引用自 MSDN :
In Microsoft C++, identifiers with two leading underscores are reserved for compiler implementations. Therefore, the Microsoft convention is to precede Microsoft-specific keywords with double underscores. These words cannot be used as identifier names.
Microsoft extensions are enabled by default. To ensure that your programs are fully portable, you can disable Microsoft extensions by specifying the ANSI-compatible /Za command-line option (compile for ANSI compatibility) during compilation. When you do this, Microsoft-specific keywords are disabled.
When Microsoft extensions are enabled, you can use the Microsoft-specific keywords in your programs. For ANSI compliance, these keywords are prefaced by a double underscore. For backward compatibility, single-underscore versions of all the double-underscored keywords except __except, __finally, __leave, and __try are supported. In addition, __cdecl is available with no leading underscore.
The __asm keyword replaces C++ asm syntax. asm is reserved for compatibility with other C++ implementations, but not implemented. Use __asm.
The __based keyword has limited uses for 32-bit and 64-bit target compilations.
虽然根据上面的引用,__int64
和 _int64
应该都可以工作,但是 Visual Studio 没有为 _int64
提供语法高亮显示。但是 _int64
也可以编译。
最佳答案
就Windows而言,打开文件的函数是CreateFile
。 .这将返回一个 HANDLE
并且由 Kernel32.dll 提供,而不是由 Visual Studio 提供。 HANDLE
可以传递给其他 Windows API 函数。
_open
and open
函数是 POSIX 兼容函数,可帮助您在 Windows 上编译为 POSIX(Linux、macOS、BSD、Solaris 等)编写的程序。这些函数由 Visual Studio 的 C 运行时定义,并且大概在内部调用 CreateFile
。该函数的 POSIX 名称是 open
,但这里的函数定义为 _open
,以防您已经在代码。该函数返回一个 int
可以传递给其他 POSIX 函数。在 Windows 上,该接口(interface)是 Visual Studio 提供的兼容 API,但在 Linux 和 macOS 上,该接口(interface)是操作系统的直接接口(interface),就像 Windows 上的 HANDLE
一样。
fopen
函数是 C 标准的一部分。它由 Visual Studio 的 C 运行时定义,并且大概在内部调用 CreateFile
。它返回一个 FILE *
,可以将其传递给 C 标准定义的其他函数。
因此,总结一下选项:
如果您需要直接使用 Windows API,例如调用 GetFileInformationByHandle
或 CreateFileMapping
,您需要一个 HANDLE
,并且您应该可能调用 CreateFile
来打开文件。
如果您有一个已经为 POSIX 系统编写的程序,那么您可以使用 open
来更轻松地将您的程序移植到 Windows。如果您只是为 Windows 编写,那么使用此界面没有任何优势。
如果您的程序只需要执行打开、读取和写入等基本文件操作,那么fopen
就足够了,它也可以在其他系统上运行。 FILE *
可以(通常是)由您的应用程序缓冲,并支持方便的操作,如 fprintf
、fscanf
和 fgets
。如果您想对 CreateFile
或 open
返回的文件调用 fgets
,您必须自己编写。
可以将文件句柄从一个 API 转换为另一个 API,但您必须注意所有权问题。 “所有权”并不是一个真正的技术概念,它只是描述了谁负责管理一个对象的状态,你要避免销毁不属于你的对象,避免同一个对象有多个所有者。
对于 Windows API,您可以使用 _open_osfhandle()
从 HANDLE
创建一个 FILE *
,并且 _get_osfhandle()
从 FILE *
中获取 HANDLE
。但是,在这两种情况下,句柄都属于 FILE *
。
对于 POSIX API,您可以使用 fdopen()
从 int
文件描述符创建一个 FILE *
,并且您可以使用 fileno()
从 FILE *
中获取 int
文件描述符。同样,在这两种情况下,文件都属于 FILE *
。
请注意,由于 Windows 文件名是 wchar_t
数组,而 macOS/Linux 等文件名是 char
数组,因此可移植性很复杂。
如果您使用不同的 C 运行时(如 MinGW),或者如果您使用适用于 Linux 的 Windows 子系统,情况就会有所不同。
关于visual-c++ - 关于 MSVC 编译器,open()、open() 和 fopen() 之间的区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44792526/
我有两个单独编译的DLL,一个是从Visual Studio2008编译的,另一个是从MATLAB编译的MEX文件。这两个DLL都包含一个头文件。当我获取一个DLL中的结构sizeof()时,它返回4
一位同事更喜欢尤达的条件:。这在团队中是一种有争议的风格,并且提出的一个论点是,如果(x=0),编译器可以一致地发出警告来检测错误模式。。然而,msvc似乎没有检测到类(https://godbolt
while (getline(stream, thisword, ' ') != 0) {... 我可以在 MSVC 2012 下编译这一行。通过传递一个“SPC”字符作为字符串分隔符,它应该测试输入
我使用较早版本的 Cocos2dx 编写游戏并使用 VS 2013 对其进行编译。请注意,我使用的是 CMake 和 Qt Creator 以及两个编译器版本。当 Cocos2dx v3.12 出来时
我正在尝试在 Windows 10 64 位下的 Python 3.8.3 上安装 chatterbot 包并遇到一个奇怪的错误,我怀疑它一定与某些目录或 PATH 设置有关,我希望这是一个简单的修复
知乎Where and why do we have to put the template and typename keywords , 我很惊讶地得知 MSVC accepts以下代码: str
在摆弄复制省略时,我遇到了这种奇怪的行为: class Obj { public: Obj() = default; Obj(Obj&&) = delete; Obj(const Obj
以下代码使用 gcc 和 clang(以及许多其他 C++11 编译器)进行编译 #include typedef int datatype; template struct to_datatyp
我已经阅读了很多帖子,但我不明白如何在命令行中使用 MSVC 在 Windows 上创建一个简单的动态库。我正在做的是: 1º) 编写 DLL 代码 动态.h #pragma once __decls
我有以下代码无法与MSVC一起编译。使用gcc,clang和icc可以正常编译。我想这是个错误,对不对? 您有/知道一些解决方法吗? #include struct A { template
我已经阅读了很多帖子,但我不明白如何在命令行中使用 MSVC 在 Windows 上创建一个简单的动态库。我正在做的是: 1º) 编写 DLL 代码 动态.h #pragma once __decls
我有一个简单的 C++ 代码,我尝试使用 Visual Studio 2019 进行编译: #include #include int main() { std::cout << "Hel
有没有办法告诉MSVC编译器在短时间内不要修改某个寄存器?就像在一个小循环中,告诉它不要使用 ebx 寄存器(它可以使用任何其他寄存器)。在这种情况下,压入和弹出寄存器不起作用,因为在我将其弹出后,M
Borland C 有伪寄存器 _AX、_BX、_FLAGS 等,可以在“C”代码中使用它们将寄存器保存到临时变量。 是否有任何 MSVC 等效项?我尝试了@AX、@BX等,但编译器(MSVC1.5)
美好的一天, 我在 C++ 中尝试新事物,我发现 Visual Studio 中的调试和发布配置给我不同的结果。 #include #include #include #include #in
我想我在 MSVC 的编译器(MSVC Ultimate 2012 版本 11.0.61030.00 更新 4)中发现了一个错误。 #include "stdafx.h" class Base { p
我正在使用 Haxe 的 HXCPP 生成 C++ 代码并使用 Microsoft Visual Studio 2010 Express Edition 对其进行编译。我正在关注 this指南,它会要
我正在使用 Microsoft Visual Studio 2008 (C++)。我有一个要在 Debug模式下构建的解决方案。我引用了一些第三方库(例如 MyGUI)。在调试构建结束时,链接器给出了
老计算机程序员遇到新问题:-) 我正在将一个 CMake 文件项目移至 Visual Studio,并且该 CMake 项目中有数百个包含路径。 我当然可以一劳永逸地修补它们,但这会经常发生在不同的机
我有下一个功能: namespace TEST { class TEST { int a; int b; }; } namespace UNION_TE
我是一名优秀的程序员,十分优秀!