在功能中包裹C块。初学者问题

时间:2011-05-23 15:54:23

标签: c++ c function getcwd

我找到了C片段来获取当前工作目录from here。基本上,代码是:

char directory[_MAX_PATH];
getcwd(directory, sizeof(directory))

我想将它抽象到另一个函数中,在另一个文件中(如果需要,可以在不同的平台上进行交换)。

目前,我有外部文件

void getCurrentDirectory(char *directory) {
    getcwd(directory, sizeof(directory));
}

并在主文件中

char directory[100];
getCurrentDirectory(directory);
printf("%s", *directory);

然而,当打印到屏幕时,我得到废话(可能尝试将内存位置打印为字符串?)

我确信这对非初学者来说是非常明显的。发生了什么事?

编辑:我在Windows 7上,顺便说一下

感谢。

8 个答案:

答案 0 :(得分:2)

您将char *的大小传递给getcwd,而不是数组的大小。

将尺寸参数传递给您的函数。

void getCurrentDirectory(char *directory, size_t size) {
    getcwd(directory, size);
}

然后:

char directory[100];
getCurrentDirectory(directory, sizeof(directory));
printf("%s", *directory);

此外,如果您使用的是Windows,则应该将数组大小更改为预定义的MAX_PATH,以避免潜在的缓冲区溢出。 getcwd需要一个长度,但我不认为所有的文件函数都可以。

答案 1 :(得分:2)

这一行: printf("%s", *directory);

应该是: printf("%s", directory);

您将第一个元素(目录[0])传递给printf,而不是指向char数组的指针。

答案 2 :(得分:2)

如果是C ++,我建议尽可能使用boost::filesystem,这会隐藏所有底层平台细节为您提供C ++样式接口而不是缓冲区溢出C函数

答案 3 :(得分:2)

你在这里犯了很多错误:

void getCurrentDirectory(char *directory) 
  {
      getcwd(directory, sizeof(directory));
  }

错误1:

`sizeof(directory)` 

给出指针的大小,准确地说是char *。您的目的是传递数组的大小,而不是指针大小。

错误2:

`printf("%s", *directory);` 

将数组的第一个元素传递给printf而不是数组的地址。您的目的是打印整个数组而不仅仅是第一个元素。

更正解决方案

你应该这样做

void getCurrentDirectory(char *directory, size_t arrSize)  
{                                         ^^^^^^^^^^^^^^
    getcwd(directory, arrSize);
}

数组的大小是显式传递的,因此函数可以使用它。

在main中打印数组的内容时:

   printf("%s", directory);

答案 4 :(得分:1)

您应该在本地分配缓冲区(必要时) 长度是已知的,实际长度需要知道)和 返回一个字符串:

std::string
getCurrentDirectory()
{
    char results[_MAX_PATH];
    if ( getcwd( results, sizeof(results) ) == NULL )
        throw std::ios_base::failure( "Could not get current directory" );
    return std::string( results );
}

另请注意,_MAX_PATH只是猜测;实际最大值是 不是编译时常量(因为它取决于文件 系统)。考虑到这一点的实现可能会 看起来像:

std::string
getCurrentDirectory()
{
    long length = pathconf( ".", _PC_PATH_MAX );
    if ( length == -1 )
        throw std::ios_base::failure(
                "Could not determine necessary buffer length to get current directory" );
    std::string results( length, '\0' );
    if ( getcwd( &results[0], results.size() ) == NULL )
        throw std::ios_base::failure( "Could not get current directory" );
    results.resize( strlen( results.c_str() );
    return results;
}

然而,如果程序只是进行,这可能是过度的 用于没有NFS或SMB安装驱动器的个人系统。

答案 5 :(得分:1)

因为它是C ++,为什么不这样做:

std::string getCurrentDirectory()
{
    char directory[_MAX_PATH] = {};
    getcwd(directory, sizeof(directory));
    return directory;
}

答案 6 :(得分:0)

您无法使用sizeof找到指针所指向的内存块的大小。它将评估指针本身的大小。

将您的功能更改为:

void getCurrentDirectory(char *directory, size_t buf_max)
{
    getcwd(directory, buf_max);
}

答案 7 :(得分:0)

现在回答你的问题:

当getcwd由于某种原因失败时,directory指向的数组内容(在您的情况下)是未定义的。因此,在您的错误实施中,您将在大多数情况下看到垃圾。 (另外,你应该检查getcwd的返回值,它失败时返回-1)

现在,您的情况失败的原因是您使用sizeof(directory)指定的大小只是指针的大小(可能是4)和当前工作目录名称中的字符正在尝试打印的不止于此。这适用于大小为3或更小的目录。

而且,最后这里的许多人已经向你解释了如何解决它。