如何避免使用常量作为文件名大小?

时间:2019-10-05 16:39:33

标签: c++ arrays vector posix

似乎标准的编程实践和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_MAXMAXNAMLEN之类,并让实现在运行时改为使用pathconf吗?

1 个答案:

答案 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样式数组编写的现有代码可能会更好。

相关问题