gpt4 book ai didi

c - 如何将函数中的字符指针数组返回给 main?

转载 作者:太空宇宙 更新时间:2023-11-04 03:18:46 26 4
gpt4 key购买 nike

我正在尝试将扩展名为 .txt 的文件列表存储到我当前工作目录中的一个数组中。我已经把数组放在一起了,现在我只需要归还它。我是 C 的新手,我不习惯指针的情况。如何返回一个 char 指针数组?我创建了数组,并根据我在目录中找到的文本文件数量对其进行了分配。

当我尝试编译时遇到两个错误,这让我相信我对指针的理解不是我想的那样。我也一直在读到从函数返回时我的数组将被销毁,因为它在堆栈上。我不确定如何解决这个问题。欢迎任何帮助或批评。

    // prototypes
char* getLine();
void replaceWord();
char * getTxtFilesInDir(char*);
bool isTxt(char *);

int main(int argc, char **argv) {

// Check to see if correct number of arguments is given
if (argc < 4) {
printf("ERROR: Not enough parameters supplied. Please supply a find,"
"replace, and prefix parameter and try again.\n");
return -1;
}

// Initialize variables
char *find, *replace, *prefix;
find=argv[1];
replace=argv[2];
prefix=argv[3];
char cd[1024];

// Get the Current working directory to grab files
if (getcwd(cd, sizeof(cd)) != NULL) {
printf("Current working dir is: %s\n", cd);
} else {
perror("getcwd() error");
}

// Get the values of the arguments
printf("Value of find: %s\nValue of replace: %s\nValue of prefix: %s\n",
find, replace, prefix);

// create an array of the files that are valid
char* files = getTxtFilesInDir(cd);

return 0;

}
char* getTxtFilesInDir(char* directory) {
DIR *d;
struct dirent *dir;
d = opendir(directory);
int n=0, i=0;

// get the number of text files in the directory
if (d) {
while((dir = readdir(d)) != NULL) {
if (isTxt(dir->d_name)) {
n++;
}
}
}

rewinddir(d);
// Create the array of text files depending on the size
static char* txtFiles[n];

// add the text files to the array
if (d) {
printf("Found: \n");
while ((dir = readdir(d)) != NULL)
{
if (isTxt(dir->d_name)) {
printf("%s\n", dir->d_name);
txtFiles[i]= (char*) malloc (strlen(dir->d_name)+1);
strncpy(txtFiles[i], dir->d_name, strlen(dir->d_name));
i++;

}
}
closedir(d);
}
return txtFiles;
}

bool isTxt(char *file) {
size_t len = strlen(file);
return len > 4 && strcmp(file + len -4, ".txt") == 0;
}

最佳答案

如果您希望 getTxtFilesInDir 返回一个字符串数组,它应该返回 char**,而不是 char*

您也不需要将变量声明为static。你声明一个变量在作为 static 的函数中,当您希望变量保持不变时函数的所有调用。在这种情况下,这可能不是您想要的做。

在不修改太多初始代码的情况下,您可以先分配内存一个字符串数组,然后在你有一个新条目时调整它的大小。在这个例子我马上就做了,因为 realloc(NULL, somesize) 和执行 malloc(somesize)。这就是初始化 *tmp = 0txtFiles = NULL,所以这个技巧有效。您还应该传递一个指向存储条目数的 size_t 的指针:

char **getTxtFilesInDir(const char* directory, size_t *len) {
if(directory == NULL || len == NULL)
return NULL;

...

*len = 0;
char **txtFiles = NULL, **tmp;
char *str;

if (d) {
printf("Found: \n");
while ((dir = readdir(d)) != NULL)
{
if (isTxt(dir->d_name))
{
tmp = realloc(txtFiles, (len+1) * sizeof *textFiles);
if(tmp == NULL)
return txtFiles; // return what you've got so far


str = malloc(strlen(dir->d_name) + 1);
if(str == NULL)
{
if(txtFiles == NULL) // first time, free everything
{
free(tmp);
return NULL;
}

return tmp; // return all you've got so far
}

strcpy(str, dir->d_name); // no need of strcnpy, you've allocated
// enough memory
txtFiles = tmp;
txtFiles[(*len)++] = tmp;
}
}
closedir(d);

return txtFiles;
}

这里的重点是 1. 如何使用 realloc 扩展内存。然后它使用 malloc 为字符串分配内存。我在 txtFiles = tmp; 之前这样做,这样我就不必写很多 if(...==NULL)。如果有事情发生沿途出错,该函数返回它已经拥有的所有文件名存储。

现在在 main 中你可以:

int main(int argc, char **argv)
{
...

size_t len = 0;
char **files = getTxtFilesInDir(cd, &len);

if(file == NULL)
{
fprintf(stderr, "No files found\n");
return 1;
}

for(size_t i = 0; i < len; ++i)
printf("file: %s\n", files[i]);

// freeing memory
for(size_t i = 0; i < len; ++i)
free(files[i]);

free(files);

return 0;
}

我也想评论一下你原来的复制方式:

strncpy(txtFiles[i], dir->d_name, strlen(dir->d_name));

strncpy 在您想限制要复制的字节数时非常有用。在你的情况你已经分配了足够的内存,所以没有必要。和当你使用 strncpy 时,限制应该绑定(bind)到字节数可用于目的地,而不是源,否则您可能会复制更多比它应该的字节。在你的情况下,你不会得到有效的 c 字符串,因为你限制复制到 dir->d_name 的长度,因此 '\0'-终止不会被复制。

man strcpy

#include <string.h>

char *strcpy(char *dest, const char *src);

char *strncpy(char *dest, const char *src, size_t n);

[...]

The strncpy() function is similar, except that at most n bytes of src are copied. Warning: If there is no null byte among the first n bytes of src, the string placed in dest will not be null-terminated.

当您使用 strncpy 时,您必须确保副本是有效的字符串自己设置 '\0' 终止字节。因为你分配了strlen(dir->d_name)+1 个字节的字符串:

strncpy(txtFiles[i], dir->d_name, strlen(dir->d_name));
textFiles[i][strlen(dir->d_name)] = 0;

此外,程序的退出值是一个无符号值,范围从 0 到 255。在 main 中,您应该在出错时返回 1 而不是 -1

关于c - 如何将函数中的字符指针数组返回给 main?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48674280/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com