【问题标题】:some strange behaviour of `stat()``stat()` 的一些奇怪行为
【发布时间】:2013-07-29 06:58:38
【问题描述】:

我想在另一个目录中创建 2 个目录。目录将具有随机生成的名称。但我遇到了stat() 函数的一些奇怪行为。

对于dirname_ 的每次调用stat() 都会返回0。但是workdir_ 里面没有文件。仍然无法找出我的代码中有什么问题。

编译于Linux computer 3.8.0-26-generic #38-Ubuntu SMP Mon Jun 17 21:43:33 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux

这里是来源:

#include <string>
#include <stdexcept>
#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>


const std::string _randomStr(const int len) {
    static const char alphanum[] =
        "0123456789"
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        "abcdefghijklmnopqrstuvwxyz";
    std::string s(len + 1, 0);
    for (int i = 0; i < len; ++i) {
        s[i] = alphanum[rand() % (sizeof(alphanum) - 1)];
    }
    return s;
}

int main(void)
{
    std::string workdir_;
    std::string dirname_;
    struct stat sb;
    int err = 0;

    do {
        workdir_ = "./" + _randomStr(10);
    } while (0 == ::stat(workdir_.c_str(), &sb));
    err = ::mkdir(workdir_.c_str(), 0755);
    if (err)
        throw std::runtime_error("failed to initialize directory");
    std::cout << "workdir: " << workdir_ << std::endl;

    do {
        dirname_ = workdir_ + "/" + _randomStr(10);
    } while (0 == ::stat(dirname_.c_str(), &sb));
    err = ::mkdir(dirname_.c_str(), 0755);
    if (err)
        throw std::runtime_error("failed to initialize directory");
    std::cout << "dirname : " << dirname_ << std::endl;     
    return 0;
}

【问题讨论】:

  • 你能把std::cout &lt;&lt; "dirname : " &lt;&lt; dirname_ &lt;&lt; std::endl; 移动到第二个循环中,看看dirname_在调用stat时实际上是什么吗?
  • 您是否考虑过使用g++ -Wall -g 进行编译并使用gdb 调试器(也许还使用strace 您的程序)?
  • 为什么你期望 stat 的输出非零?

标签: c++ linux stat errno


【解决方案1】:

您的dirname_ 中有一个虚假的\0。当您在循环内打印目录名称并通过 strace 运行时,输出看起来像

write(2, "dirname : ", 10)              = 10
write(2, "./zLOZ2nOXpP\0/7U20o0J90x\0", 25) = 25
write(2, "\n", 1)                       = 1
stat("./zLOZ2nOXpP", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0

所以,cerrcout 正确打印字符串(使用它的长度),但是当转换为带有 c_str() 的 C 字符串时,结果只是第一个目录名称,然后传递给 @987654327 @。

【讨论】:

  • 为了完整起见,修复方法是更新_randomStr() 以将字符串初始化为std::string s(len, 0); 以消除尾随的NULL 字符。 c_str() 自动将 NULL 字符附加到它返回的 char* 的末尾。
  • @TheCodeArtist 谢谢 - 我实际上也让代码像这样工作,但不是 100% 确定这是否会导致任何一次性错误,所以我犹豫着发布它......跨度>
  • @Andreas 您的回答绝对正确。 _randomStr() 中的这个错误是一种复制粘贴错误。此功能适用于char*erlier。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-10-13
  • 1970-01-01
  • 1970-01-01
  • 2019-03-12
  • 1970-01-01
  • 1970-01-01
  • 2017-09-21
相关资源
最近更新 更多