我试图将扩展名为.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;
}
答案 0 :(得分:1)
如果你希望getTxtFilesInDir
返回一个字符串数组,它应该
返回char**
,而不是char*
。
此外,您无需将变量声明为static
。你声明一个变量
在函数static
中,当您希望变量保持不变时
所有函数调用。在这种情况下,这可能不是你想要的
做。
如果不修改过多的初始代码,可以先分配内存
对于一个字符串的arrray,然后在你有一个新的条目时调整它的大小。在
这个例子我立即这样做,因为realloc(NULL, somesize)
与...相同
做malloc(somesize)
。这就是为什么初始化*tmp = 0
和。{
txtFiles = 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
时,限制应该绑定到字节数
可用于目的地,而不是源,否则您可能会复制更多
字节比它应该的。在您的情况下,您将无法获得有效的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);
[...]
strncpy()
函数类似,只是复制了n
个src
个字节。 警告:如果第一个n
中没有空字节src
的字节,dest中的字符串不会以空值终止。
当您使用strncpy
时,必须确保该副本是有效的字符串
自己设置'\0'
- 终止字节。因为你已经分配了
字符串的strlen(dir->d_name)+1
个字节:
strncpy(txtFiles[i], dir->d_name, strlen(dir->d_name));
textFiles[i][strlen(dir->d_name)] = 0;
程序的退出值也是unsigned
值,从0到255。
在main
中,您应该在出错时返回1
而不是-1
。