Arrays 尝试将数组字符串作为动态存储的内存返回,但不起作用
我是C编程新手,目前正在编写一个函数,将字符串复制到字符串数组中,并返回给它的调用者。我已经测试了函数,函数中的一切都很好。(例如:printf函数中的string元素以显示它实际上存储在数组中)但是当我返回string数组时,输出没有显示任何内容 我提到过,但这里的方法似乎对我不起作用 这是我的函数名为Arrays 尝试将数组字符串作为动态存储的内存返回,但不起作用,arrays,c,string,Arrays,C,String,我是C编程新手,目前正在编写一个函数,将字符串复制到字符串数组中,并返回给它的调用者。我已经测试了函数,函数中的一切都很好。(例如:printf函数中的string元素以显示它实际上存储在数组中)但是当我返回string数组时,输出没有显示任何内容 我提到过,但这里的方法似乎对我不起作用 这是我的函数名为 #define ROWS 4 #define WORDS_COUNT 50 char **toStrArray(char str[], char **strArr) { int i
#define ROWS 4
#define WORDS_COUNT 50
char **toStrArray(char str[], char **strArr)
{
int i, j, iTmp;
int len;
char *tmp; /* Temporary string to copy each words */
len = strlen(str);
tmp = (char*)malloc(len * sizeof(char));
j = 0; iTmp = 0;
/* ASSERTION: Iterate through str and assign the string to strArr */
for( i = 0; str[i] != '\0'; i++ )
{
if( str[i] == ' ' )
{
*(strArr + j) = tmp; /* Assign the copied words to strArr */
/* printf("%s\n", *(strArr + j)); < for testing purposes only */
iTmp = 0; /* Reset back to 0 */
memset(tmp, 0, len * sizeof(char));
j++; /* Move to next row */
}
else
{
tmp[iTmp] = str[i]; /* Copy the words in str to tmp */
iTmp++;
}
}
*(strArr + j) = tmp; /* Store the last words in the string because the last words is not end with ' '
but rather '\0' */
/* printf("%s\n", *(strArr + j)); < for testing purposes only */
/* Ensures no memory leak */
free(tmp);
tmp = NULL;
return strArr;
}
#定义第4行
#定义单词\u计数50
字符**toStrArray(字符str[],字符**strArr)
{
int i,j,iTmp;
内伦;
char*tmp;/*复制每个单词的临时字符串*/
len=strlen(str);
tmp=(char*)malloc(len*sizeof(char));
j=0;iTmp=0;
/*断言:遍历str并将字符串分配给strArr*/
对于(i=0;str[i]!='\0';i++)
{
如果(str[i]='')
{
*(strArr+j)=tmp;/*将复制的单词分配给strArr*/
/*printf(“%s\n”,*(strArr+j));<仅用于测试*/
iTmp=0;/*重置回0*/
memset(tmp,0,len*sizeof(char));
j++;/*移动到下一行*/
}
其他的
{
tmp[iTmp]=str[i];/*将str中的单词复制到tmp*/
iTmp++;
}
}
*(strArr+j)=tmp;/*存储字符串中的最后一个单词,因为最后一个单词不以“”结尾
而是“\0”*/
/*printf(“%s\n”,*(strArr+j));<仅用于测试目的*/
/*确保没有内存泄漏*/
免费(tmp);
tmp=NULL;
返回斯特拉尔;
}
主叫函数:
输出只是“,”
char str[]=“这茶很好”;
字符**arg_1;
int i;
/*arg_1的字符串数组的分配*/
arg_1=(char**)malloc(ROWS*sizeof(char*));
/*断言:遍历字符串数组的行并分配它们的内存*/
对于(i=0;i<4;i++)
*arg_1=(char*)malloc(WORDS_COUNT*sizeof(char));
arg_1=toStrArray(str,arg_1);
对于(i=0;i<4;i++)
printf(“%s,”,*(arg_1+i));
printf(“\n”);
关于
arg_1 = toStrArray(str, arg_1);
这将覆盖指向以前通过调用malloc()
分配的动态内存的指针。这将导致无法恢复的内存泄漏。建议:
for( size_t i = 0; i < 4; i++ )
{
strcpy( argv_1[i], str );
}
但是这里的方法似乎对我不起作用
在该代码中,“字符串数组”声明为
char sub_str[10][20]; // [1]
您将函数声明为
char** toStrArray(char str[], char **strArr): // [2]
这些是不同的动物
一般来说,您不会混合使用[]和**符号。您只需声明
char** toStrArray(char* str, char** strArr); // [3]
返回的值将与strArr
相同。原因是可以方便地在表达式中使用函数调用。例如,请参见fgets()
但是
- 这两个数组本身都不是字符串数组
- [1] 是一个由10 x 20
组成的块,从地址char
sub_str
char sub_str[10][20];
char** strArray;
- [2] 是指向
char
char** strArray;
是指向*strArray
char
char** strArray;
是一个**strArray
字符
char** strArray;
- 它永远不会是一个字符数组,但它可以是一个指向字符数组的指针数组,这将是最灵活的用法,因为我们可以迭代
所指向的指针,编写类似**strArray
,*strArray[0]
等代码。字符串数组*srtArray[1]
10*20*sizeof(char)
字节的区域。在C中没有多维数组。每个20字节的段只是从&sub\u str
开始一个接一个地排列
由于每个字符串都是以null结尾的,我们最多可以有10个字符串,每个字符串的大小可达19字节
#include <stdio.h>
int main(void)
{
char sub_str[10][20];
for (int i = 0; i < 10; i += 1)
sprintf(
sub_str[i],
"%16s%03d",
"This is string ", i+1
);
for (int i = 0; i < 10; i += 1)
printf(
"%2d %s len(%zd)\n",
i, sub_str[i], strlen(sub_str[i])
);
return 0;
};
我们有一个字符串数组。请参见下面的迭代访问第i个字符串
printf(
"%2d %s len(%zd)\n",
i, sub_str[i], strlen(sub_str[i])
);
这里的问题是,我们几乎没有灵活性,可能浪费了大量内存。所有大小都是固定的,静态的
建筑char**strArray;
最终
这是最灵活和最熟悉的方法,因为每个C程序都至少使用一个case。main()
具有通用原型
int main(int argc, char** argv);
在这里,我们看到您的程序中缺少一个非常重要的东西:因为srtArray
只是一个指针,您需要知道它指向多少个指针。
本身*strArray
只是一个指向char
的指针,并且只有在它被分配的情况下。通过声明char**strArr;
您只会得到一个指针,事实上,它是安全的
char** strArr = NULL;
考虑一下这一点
typedef struct
{
int argc;
char** argv;
} stringArray;
现在收支相抵,事实上你可以宣布
void toStrArray(char* str, stringArray strArr);
然后将argc
值打包到struct
中
关于程序:代码只是模仿系统对main()
所做的操作,从命令行参数构建字符串列表,甚至包括作为第一个参数的程序名。然后调用此函数
int just_like_main(int argc, char** argv)
这会打印出论点
它执行您在功能中必须执行的操作。
请注意,必须有一种方法可以随时控制数组中字符串的数量,就像argc
#define _BLOCK_ 4 #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct { int argc; char** argv; } stringArray; int just_like_main(int, char**); int main(void) { const int n_parm = 16; const char* test_strings[16] = { "Creating", "a", "block", "of", "strings", ",", "just", "like", "the", "system", "does", "for" , "main()", "for", "every", "program" }; stringArray ex; // example int N = _BLOCK_; // 1st block ex.argc = 0; ex.argv = (char**)malloc(sizeof(char*) * _BLOCK_); const char* program_name = "full path of program"; ex.argv[ex.argc] = (char*)malloc(1 + strlen(program_name)); strcpy(ex.argv[ex.argc], program_name); ex.argc += 1; // 1st arg. That was easy // loads all other strings into **argv for (int i = 0; i < n_parm; i += 1) { // each one if (ex.argc >= N) { // block is full N = N + _BLOCK_; char* new_block = realloc(ex.argv, (N * sizeof(char*))); printf("Block extended for a total of %d pointers\n", N); ex.argv = (char**)new_block; }; ex.argv[ex.argc] = (char*)malloc(1 + strlen(test_strings[i])); strcpy(ex.argv[ex.argc], test_strings[i]); ex.argc += 1; }; // for() printf("\t%d strings in the block:\n", ex.argc); for (int i = 0; i < ex.argc; i += 1) { printf("\t\t%d of %d: '%s'\n", 1 + i, ex.argc, ex.argv[i]); }; // now trims the end of the block // allocated: N. // used: argc printf("\t%d pointers allocated\n", N); printf("\t%d arguments read\n", ex.argc); if (N == ex.argc) printf("\tNothing to free()\n"); else { printf("\t%d pointers to free\n", N - ex.argc); char* new_size = realloc(ex.argv, (ex.argc * sizeof(char*))); printf("\tBlock size trimmed for a total of %d pointers\n", ex.argc); ex.argv = (char**)new_size; }; printf("\tCalling just_like_main() with these args\n"); int res = just_like_main(ex.argc, ex.argv); printf("\n\n\t\"main()\" returned %d\n", res); printf("\tNow fres the block and exit\n"); for (int i = 0; i < ex.argc; i += 1) free(ex.argv[i]); free(ex.argv); printf("\n\nGame over\n"); return 0; }; int just_like_main(int argc, char** argv) { printf("\n\tAt \"main()\": %d arguments\n\n", argc); for (int i = 0; i < argc; i += 1) printf("%8d\t'%s'\n", i, argv[i]); return 0; }; // just_like_main()
Block extended for a total of 8 pointers
Block extended for a total of 12 pointers
Block extended for a total of 16 pointers
Block extended for a total of 20 pointers
17 strings in the block:
1 of 17: 'full path of program'
2 of 17: 'Creating'
3 of 17: 'a'
4 of 17: 'block'
5 of 17: 'of'
6 of 17: 'strings'
7 of 17: ','
8 of 17: 'just'
9 of 17: 'like'
10 of 17: 'the'
11 of 17: 'system'
12 of 17: 'does'
13 of 17: 'for'
14 of 17: 'main()'
15 of 17: 'for'
16 of 17: 'every'
17 of 17: 'program'
20 pointers allocated
17 arguments read
3 pointers to free
Block size trimmed for a total of 17 pointers
Calling just_like_main() with these args
At "main()": 17 arguments
0 'full path of program'
1 'Creating'
2 'a'
3 'block'
4 'of'
5 'strings'
6 ','
7 'just'
8 'like'
9 'the'
10 'system'
11 'does'
12 'for'
13 'main()'
14 'for'
15 'every'
16 'program'
"main()" returned 0
Now free() the block and exit
Game over
int just_like_main(int argc, char** argv);