似乎标准的编程实践和POSIX标准彼此矛盾。我正在使用一个程序,我注意到我看到很多东西,例如:
char buf[NAME_MAX + 1]
我还看到很多操作系统没有定义NAME_MAX
并说从技术上讲它们并不需要按照POSIX,因为您应该使用pathconf来获取值它被配置为在运行时,而不是将其硬编码为常量。
问题是编译器不允许我将pathconf与数组一起使用。即使我尝试将pathconf的结果存储在const int中,它仍然会抛出拟合,并说它必须是一个常量。因此,看起来为了实际使用pathconf,我将不得不避免在此处的缓冲区中使用字符数组,因为这显然不够好。所以我陷入了困境,因为C ++标准似乎不允许我做POSIX所说的事情,那就是在运行时而不是编译时确定文件名字符缓冲区的大小。
我唯一能够找到的信息表明,我需要用向量替换数组,但是尚不清楚如何实现。当我使用一个简单的程序进行测试时,我可以使其正常工作:
std::vector<char> buf((pathconf("/", _PC_NAME_MAX) + 1));
然后我可以通过调用buf.size()
或其他方法来确定大小。但是我不确定这是否是正确的方法。有没有人有过尝试使程序停止运行的经验,这取决于在系统头文件中定义的常量NAME_MAX
或MAXNAMLEN
之类,并让实现在运行时改为使用pathconf吗?
答案 0 :(得分:0)
中途措施确实会导致某种冲突。
const usigned NAME_MAX = /* get the value at runtime */;
char buf[NAME_MAX + 1];
第二行声明一个C风格的数组(大概),该数组用于保存C风格的字符串。在C语言中,这很好。在C ++中,存在一个问题,因为NAME_MAX
的值在编译时未知。这就是为什么我称其为“中途测量”的原因-C语言风格的代码和C ++编译混合在一起。 (某些编译器将允许使用C ++。显然,您的不允许。)
C ++方法将使用C ++样式的字符串,如下所示:
std::string buf;
就是这样。不需要指定大小,因为可以避免使用C风格的接口,因此可以根据需要分配内存。合理时使用流式传输(>>
)。如果缓冲区是由用户或文件输入填充的,那应该就是您所需要的。
如果您需要使用C样式的字符串(也许此缓冲区是由为C编写的系统调用填充的?),则有一些选项可以分配所需的空间。最简单的可能是向量,就像您在想的那样。
std::vector<char> buf{NAME_MAX + 1};
system_call(buf.data()); // Send a char* to the system call.
或者,您可以使用C ++样式的字符串,这可以使操作数据更加方便。
std::string buf{NAME_MAX + 1, '\0'};
system_call(buf.data()); // Send a char* to the system call.
还有一个智能指针选项,但是vector
方法对于为C样式数组编写的现有代码可能会更好。