当文件存在时,Linux中的fopen(Lubuntu)会返回NULL
fopen in Linux (Lubuntu) returns NULL when the file exists
我正在使用Oracle的VirtualBox在虚拟机中的Lubuntu上运行此程序。我不认为这会影响任何事情,但我只是觉得值得一提。
错误似乎是从以下函数返回的字符串末尾附加的奇怪符号中出现的:
inline std::string f_settings_get(std::string val){
int index=0;
while(strcmp(val.c_str(),f_settings[0][index].c_str())!=0){
index++;
};
// For debugging purposes - printf("n%st%s",f_settings[0][index].c_str(),f_settings[1][index].c_str());
return f_settings[1][index];
}
我看不出这个函数有什么问题,因此相信它可能是由存储在变量中的数据引起的。
我一直在尝试使用fopen
打开程序中的一个文件,但遇到了标题中所述的错误。代码在Windows中运行得很好(我已经考虑了每个操作系统的/
和);然而,当在Linux上运行时,尽管它编译得很好,但我得到的错误是该文件不存在。我在网上查看了一下,发现了其他人遇到的几个问题,比如:
文件名实际上不是正确的文件名
没有访问文件的权限
访问文件是通过调用"file.txt"而不是整个目录来完成的
我使用提供的Python脚本签出了第一个文件,并用新名称重新创建了该文件。这并没有奏效(Python脚本显示文件名很好)。
我使用chmod -R 777 clesis
将所有权限设置为777,但这不起作用(尽管我没想到这是权限问题,因为它说文件不存在)。
我已经调用了完整的路径,并仔细检查了路径。这是正确的。
最后,我在代码中运行以下内容来再次检查:(a)文件存在,(b)我正在尝试打开正确的文件。
tmp_s="";
tmp_s = homeDir+binP+f_settings_get("xxxxx"); // Note, you can easily get whatever variable you want using either f_settings_get or num_settings_get
tmp_file = fopen(tmp_s.c_str(), "r+");
printf("n Running the following command: /home/xxxxx/programming/xxxxx/binn");
std::system("ls -l /home/xxxxx/programming/xxxxx/bin");
getWait();
printf("n Tried to open: %s", tmp_s.c_str());
if (tmp_file == NULL){
printf("n");
perror("Error loading dimensions.sim");
printf("Press enter to exit...");
getWait();
exit(1);
}
下面是输出的样子(很抱歉审查了内容。我向你保证用户名和文件夹拼写相同):
输出显示如下:
Filenames Loaded...
Loading Settings from sim file...
++++++++++++++++++++++++++++++++++++++++++++++++++ Settings Loaded...
Loading System Dimensions from sys file...
--------------------------------------------------
Running the following command: /home/xxxxx/programming/xxxxx/bin
total 636
-rwxrwxrwx 1 xxxxx xxxxx 958 Jul 25 20:59 dimensions.sim
Tried to open: /home/xxxxx/programming/xxxxx/bin/dimensions.sim
Error loading dimensions.sim: No such file or directory
Press enter to exit...
如果文件路径直接指定为"bin/dedimensions.sim"或"/home/xxxxxx/programing/xxxxxx/bin/dimensions.sim",则它可以正常工作。这使我得出了一个困惑的结论。在tmp_s
从std::string
到c_str
的转换过程中,存在导致错误目录路径的问题。但是,我使用的任何其他文件都不会出现这种情况,而且我在Windows计算机上从未遇到过这种问题。因此,我对可能是什么原因造成的感到困惑
最后一个观察结果——无论如何,转换都是使用printf("tmps = %s",tmp_s.c_str());
打印出来的。很明显,这并不"奇怪"。
您的问题很可能来自杂散回车(十六进制0D
,通常在C中写成r
),这在使用unix-y库读取windows-y文件时很常见。Windows文件的行以CR-LF,十六进制0D0A
结尾,而unix只使用一个LF,十六进制0A
。对于未以二进制模式打开的文件,Windows C stdio将把一个CRLF映射到一个LF(n
)上。在Unix中,文件是以二进制模式还是ASCII模式打开并不重要,因为不会发生重新映射。
结果是,在Windows程序上编译的同一程序可以读取Windows文件,在Unix上编译的程序可以读取Unix文件;在这两种情况下,线路终止符看起来都像一个单独的n
。Windows程序通常也可以读取Unix文件。但是Unix程序在读取Windows文件时,会在每一行的末尾看到一个游离的CR、r
、十六进制0D
。
这尤其困扰配置实用程序。假设您有一个格式为的配置文件
some_setting=27
some_file=dimensions.sim
等等。
现在,配置读取器读取每一行,在=
处对其进行拆分,并将第一部分用作键,将第二部分用作值。它甚至可能将一些值转换为数字。
现在,如果文件是在Windows上创建的(无论它当前是在Windows还是在您的笔记本电脑上),Unix配置读取器将看到some_setting
的值为27r
,some_file
的值为dimensions.simr
。第一个不会引起任何问题,除非配置系统是偏执的,因为atoi
和strtod
最多转换为第一个非数字字符,只要至少有一个数字,就不要抱怨。但是字符串不能作为文件名使用,因为文件名末尾不太可能有r
。
使这个问题特别隐蔽的是,当您试图打印出有问题的字符串时,r
实际上充当了回车;也就是说,它将光标返回到行的开头。如果下一个输出字符是n
,则r
是完全不可见的。如果下一个输出是一些消息,它将被套印在线路上,这是非常令人困惑的。
- 如果我std::dynamic_pointer_cast并且底层dynamic_cast的结果为null,那么返回的sh
- 如何在 c++ 中'NULL'字符串
- c++使用foreach使数组为null
- 当使用通配符和null指针调用函数时,对输出的说明
- 当字段可以为null时,如何使用C++接口在Avro中写入数据
- 如何在映射中返回null
- 为什么返回 NULL 不会破坏函数?
- 构造函数中的 QQuickItem 父项 null
- 检查字符串是否"null" C++
- fopen 在 gdb 中返回 NULL
- what(): basic_string::_M_construct null not valid
- 在这个函数中是有缺陷的,因为取消引用 null 是无效的,所以我想更改代码
- 为什么在排序链表上的这种合并实现总是将两个列表都设置为 NULL,而只有一个应该设置一个列表?
- 为什么要从main()返回NULL?
- 为什么 nlohmann/json 序列化 "null" 而不是在 double 上"0"?
- 当目标指针不是基类的类型时,为什么允许dynamic_cast为多态类生成 null 指针?
- 是否有通用方法可以找到任何以 null 结尾的字符串的长度?
- 为什么TinyXML2的XMLDocument::FirstChild()函数在尝试解析这个有效的XML文件时返回NULL?
- 使用 curl_easy_cleanup(curl) 时收到未经处理的 NULL 异常
- 当文件存在时,Linux中的fopen(Lubuntu)会返回NULL