将C块包装在函数中。初学者问题

| 我找到了C片段来从这里获取当前的工作目录。本质上,代码是:
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,顺便说一句 谢谢。     
已邀请:
您在这里做错了很多事情:
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);
}
数组的大小是显式传递的,因此函数可以使用它。 在主打印数组内容时:
   printf(\"%s\", directory);
    
这行:
printf(\"%s\", *directory);
应该:
printf(\"%s\", directory);
您正在将第一个元素(目录[0])传递给printf,而不是char数组的指针。     
如果是C ++,我建议尽可能使用boost :: filesystem,它会隐藏所有底层平台详细信息,并为您提供C ++样式的接口,而不是容易发生缓冲区溢出的C函数。     
您正在将char *的大小传递给getcwd,而不是数组的大小。 将size参数传递给函数。
void getCurrentDirectory(char *directory, size_t size) {
    getcwd(directory, size);
}
接着:
char directory[100];
getCurrentDirectory(directory, sizeof(directory));
printf(\"%s\", *directory);
另外,如果您使用的是Windows,则应将阵列大小更改为预定义的“ 12”,以避免潜在的缓冲区溢出。 getcwd需要一定的长度,但是我不认为所有文件功能都可以。     
您应该在本地分配缓冲区(必要时 长度是已知的,实际长度需要是已知的)和 返回一个字符串:
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 );
}
还要注意that14ѭ只是一个猜测;实际的最大值是 不是编译时间常数(因为它取决于文件 系统)。考虑到这一点的实现可能 看起来像:
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的驱动器的个人系统上使用。     
由于它是C ++,为什么不这样做:
std::string getCurrentDirectory()
{
    char directory[_MAX_PATH] = {};
    getcwd(directory, sizeof(directory));
    return directory;
}
    
不能像这样用ѭ17cannot找出指针所指向的存储块的大小。它将评估为指针本身的大小。 将功能更改为:
void getCurrentDirectory(char *directory, size_t buf_max)
{
    getcwd(directory, buf_max);
}
    
现在回答您的要求: 当getcwd由于某种原因而失败时,由
directory
指向的数组的内容(在您的情况下)未定义。因此,通过错误的实现,在大多数情况下,您会看到垃圾。 (另外,您应该检查来自
getcwd
的返回值,失败时返回-1) 现在,失败的原因是您使用
sizeof(directory)
指定的大小仅仅是指针的大小(可能为4),并且您要打印的当前工作目录名称中的字符超过了那。对于大小为3或更小的目录,此方法将正常工作。 最后,这里的许多其他人已经向您说明了如何解决它。     

要回复问题请先登录注册