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

发布于 2024-11-09 05:17:47 字数 693 浏览 0 评论 0原文

我找到了 C 代码片段来获取当前工作目录从这里< /a>.本质上,代码是:

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,顺便说一句,

谢谢。

I found the C snippet to get the current working directory from here. Essentially, the code is:

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

I want to abstract that into another function, in a different file (so it can be swapped out on different platforms if necessary).

Currently, I have in the external file

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

and in the main file

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

However, when printing to screen, I get nonsense (possibly trying to print memory location as a string?)

I'm sure it's something blindingly obvious to a non-beginner. What's going on?

Edit: I'm on Windows 7, btw

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

苦行僧 2024-11-16 05:17:47

您在这里做错了很多事情:

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);

Theres a number of things that you are doing wrong here:

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

Mistake 1:

`sizeof(directory)` 

gives you size of a pointer, to be precise, char *. Your intention is to pass size of the array, and not the pointer size.

Mistake 2:

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

Passes first element of the array to the printf not the address of the array. Your intention is to print the entire array not just the first element.

Corrected Solution

You should be doing

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

Size of the array is passed explicitly so the function can just use it.

In the main while printing the contents of the array:

   printf("%s", directory);
初懵 2024-11-16 05:17:47

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

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

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

This line:
printf("%s", *directory);

should be:
printf("%s", directory);

You're passing in the first element (directory[0]) to the printf, not the pointer to the char array.

念﹏祤嫣 2024-11-16 05:17:47

如果是 C++,我建议使用 boost::filesystem如果可能的话,它会隐藏所有底层平台详细信息,并为您提供 C++ 风格的接口,而不是易于缓冲区溢出的 C 函数。

If it's C++ I'd suggest using boost::filesystem if at all possible, which hides all of the underlying platform details and gives you C++ style interface instead of the buffer overflow prone C functions.

幸福丶如此 2024-11-16 05:17:47

您将 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 需要一个长度,但我不认为所有的文件函数都需要一个长度。

You are passing the size of a char* to getcwd, instead of the size of the array.

Pass a size parameter to your function.

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

and then:

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

Also, if you're using Windows, you should probably change your array size to the predefined MAX_PATH to avoid a potential buffer overflow. getcwd takes a length, but I don't think all of the file functions do.

抚你发端 2024-11-16 05:17:47

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

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 驱动器的个人系统。

You should be allocating the buffer locally (where the necessary
length is known, and the actual length needs to be known) and
returning a string:

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 );
}

Note too that _MAX_PATH is only a guess; the actual maximum is
not a compile time constant (since it depends on the file
system). An implementation which takes this into account might
look something like:

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;
}

This is probably overkill, however, if the program is only going
to be used on a personal system with no NFS or SMB mounted drives.

温馨耳语 2024-11-16 05:17:47

既然是C++,为什么不这样做:

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

Since it is C++, why not do this:

std::string getCurrentDirectory()
{
    char directory[_MAX_PATH] = {};
    getcwd(directory, sizeof(directory));
    return directory;
}
人生百味 2024-11-16 05:17:47

您无法像这样使用 sizeof 找出指针所指向的内存块的大小。它将计算出指针本身的大小。

将您的功能更改为:

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

You cannot find out the size of a memory block pointed at by a pointer using sizeof like that. It will evaluate to the size of the pointer itself.

Change your function to:

void getCurrentDirectory(char *directory, size_t buf_max)
{
    getcwd(directory, buf_max);
}
陈独秀 2024-11-16 05:17:47

现在回答您的问题:

当 getcwd 由于某种原因失败时,directory 指向的数组的内容(在您的情况下)是未定义的。因此,在大多数情况下,通过有缺陷的实现,您会看到垃圾。 (另外,您应该检查 getcwd 的返回值,失败时返回 -1)

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

最后,这里的许多其他人已经向您解释了如何修复它。

Now to answer what you've asked:

When getcwd fails for some reason the contents of the array pointed to by directory (in your case) is undefined. Therefore, with your buggy implementation you will see junk in most cases. (Also, you should check return value from getcwd, it returns -1 when it fails)

Now, the reason for failure in your case is the size that you are specifying using sizeof(directory) is just the size of a pointer (which would likely to be 4) and characters in the name of current working directory you are trying to print are more than that. This will work fine for directory of size 3 or less.

And, finally many others here have already explained you how to possibly fix it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文