C中的字符串动态分配
string dynamic allocation in C
我正在编写一个函数,需要:
从用户那里得到一个完整的句子
为每个单词动态分配一个可以包含它的内存块
复制到里面,保存地址到*words指针数组
我写了一个循环,在每次迭代中从用户插入的句子中获取一个词,但我无法正确地动态分配它。
这是我的:
char str[50];
while(scanf("%s", str) != EOF)
{
int len = strlen(str);
char *words = (char*) malloc((len+1)*sizeof(char));
}
我还需要确保:
如果函数成功,它returns输入的单词数。
如果内存分配失败函数returns -1.
条件 while(scanf("%s", str) != EOF)
是一个潜在的无限循环,只有当您通过命令行向程序提供 EOF
信号时才会停止。
对于包含所有单词的单个字符串,您需要在每次读取时重新分配内存以增加保存字符串的内存space。
你可以这样做:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int ret_words(char **words) { //double pointer argument
char str[50];
char *temp = malloc(1); //first allocation required
int count = 0;
if(temp == NULL){ //allocation error
return -1;
}
do{
temp = realloc(temp, strlen(str) + strlen(temp) + 2); //reallocate space on
//each iteration
if(temp == NULL){
return -1;
}
count++; //count words
} while (scanf("%49s", str) == 1 && strcat(temp, str) //scan str and append to temp
&& getchar() != '\n' && strcat(temp, " ")); //with spaces between
*words = temp; //assign temp to words
return count; //return word count
}
int main() {
int ret;
char *words; //pointer to the array of strings
puts("Enter the string");
putchar('>');
ret = ret_words(&words); //returned number of words on success, -1 on error
printf("Inputed string: %s\nNumber of words: %d", words, ret); //test print
}
约束:在循环结束的最后一个输入单词之后不能有任何 spaces。
现在,如果您想要像结构这样的二维数组,不仅为单词本身动态分配,而且为指向这些字符串的指针动态分配,您将需要一些更特殊的东西,一个三重指针。
将其视为指向字符串数组的指针,这是您需要作为函数参数的内容,以便使调用函数(在本例中为主函数)中的更改永久生效。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int ret_words(char ***words) { //triple pointer argument
char str[50];
int count = 0;
char **temp = malloc(sizeof *temp); //allocate a pointer to pointer to char
if(temp == NULL){ //allocation error
return -1;
}
do {
temp = realloc(temp, (count + 1) * sizeof *temp); //reallocate space at every scan
if(temp == NULL){
return -1;
}
temp[count] = malloc(strlen(str) + 1);
count++;
} while (scanf("%49s",temp[count - 1]) == 1 //scan str and append to temp
&& getchar() != '\n'); //with spaces between
*words = temp; //assing the allocated array of pointer to the argument
return count; //return word count
}
int main()
{
char **words; // pointer to pointer to navigate the array of strings
int ret;
puts("Enter the string");
putchar('>');
ret = ret_words(&words); //returned number of words on success, -1 on error
for(int i = 0; i < ret; i++) //print each stored one word string
printf("Word %d: %s\n",i + 1, words[i]);
printf("Word count: %d", ret); //print the number of words
}
约束:在循环结束的最后一个输入单词之后不能有任何 spaces。
请注意,由于这些赋值是通过函数的参数进行的,因此存在额外的间接级别,如果它们要在适当的位置使用或由函数返回,您只需要一个简单的指针,在第一个样本中,在第二个样本中是双指针。
假设以下限制已嵌入到您的代码片段中:
- 最大字长为49字节,
- 用户在句子结束后发出文件结束信号。
这是一个构造指针数组的简单函数:
#include <stdio.h>
#include <stdlib.h>
struct context {
char **array;
int count;
};
int read_sentence(struct context *cp) {
char buf[50];
cp->array = NULL;
cp->count = 0;
while (scanf("%49s", buf) == 1) {
// another word was read
char **new_array = realloc(cp->array, (cp->count + 1) * sizeof(*new_array));
char *p = strdup(buf);
if (new_array == NULL || p == NULL) {
// allocation error: free previously allocated memory and return -1
free(p);
if (new_array != NULL) {
cp->array = new_array;
}
while (cp->count > 0) {
free(cp->array[--cp->count]);
}
free(cp->array);
cp->array = NULL;
return -1;
}
cp->array = new_array;
cp->array[cp->count++] = p;
}
return cp->count;
}
我正在编写一个函数,需要:
从用户那里得到一个完整的句子
为每个单词动态分配一个可以包含它的内存块
复制到里面,保存地址到*words指针数组
我写了一个循环,在每次迭代中从用户插入的句子中获取一个词,但我无法正确地动态分配它。 这是我的:
char str[50];
while(scanf("%s", str) != EOF)
{
int len = strlen(str);
char *words = (char*) malloc((len+1)*sizeof(char));
}
我还需要确保:
如果函数成功,它returns输入的单词数。
如果内存分配失败函数returns -1.
条件 while(scanf("%s", str) != EOF)
是一个潜在的无限循环,只有当您通过命令行向程序提供 EOF
信号时才会停止。
对于包含所有单词的单个字符串,您需要在每次读取时重新分配内存以增加保存字符串的内存space。
你可以这样做:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int ret_words(char **words) { //double pointer argument
char str[50];
char *temp = malloc(1); //first allocation required
int count = 0;
if(temp == NULL){ //allocation error
return -1;
}
do{
temp = realloc(temp, strlen(str) + strlen(temp) + 2); //reallocate space on
//each iteration
if(temp == NULL){
return -1;
}
count++; //count words
} while (scanf("%49s", str) == 1 && strcat(temp, str) //scan str and append to temp
&& getchar() != '\n' && strcat(temp, " ")); //with spaces between
*words = temp; //assign temp to words
return count; //return word count
}
int main() {
int ret;
char *words; //pointer to the array of strings
puts("Enter the string");
putchar('>');
ret = ret_words(&words); //returned number of words on success, -1 on error
printf("Inputed string: %s\nNumber of words: %d", words, ret); //test print
}
约束:在循环结束的最后一个输入单词之后不能有任何 spaces。
现在,如果您想要像结构这样的二维数组,不仅为单词本身动态分配,而且为指向这些字符串的指针动态分配,您将需要一些更特殊的东西,一个三重指针。
将其视为指向字符串数组的指针,这是您需要作为函数参数的内容,以便使调用函数(在本例中为主函数)中的更改永久生效。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int ret_words(char ***words) { //triple pointer argument
char str[50];
int count = 0;
char **temp = malloc(sizeof *temp); //allocate a pointer to pointer to char
if(temp == NULL){ //allocation error
return -1;
}
do {
temp = realloc(temp, (count + 1) * sizeof *temp); //reallocate space at every scan
if(temp == NULL){
return -1;
}
temp[count] = malloc(strlen(str) + 1);
count++;
} while (scanf("%49s",temp[count - 1]) == 1 //scan str and append to temp
&& getchar() != '\n'); //with spaces between
*words = temp; //assing the allocated array of pointer to the argument
return count; //return word count
}
int main()
{
char **words; // pointer to pointer to navigate the array of strings
int ret;
puts("Enter the string");
putchar('>');
ret = ret_words(&words); //returned number of words on success, -1 on error
for(int i = 0; i < ret; i++) //print each stored one word string
printf("Word %d: %s\n",i + 1, words[i]);
printf("Word count: %d", ret); //print the number of words
}
约束:在循环结束的最后一个输入单词之后不能有任何 spaces。
请注意,由于这些赋值是通过函数的参数进行的,因此存在额外的间接级别,如果它们要在适当的位置使用或由函数返回,您只需要一个简单的指针,在第一个样本中,在第二个样本中是双指针。
假设以下限制已嵌入到您的代码片段中:
- 最大字长为49字节,
- 用户在句子结束后发出文件结束信号。
这是一个构造指针数组的简单函数:
#include <stdio.h>
#include <stdlib.h>
struct context {
char **array;
int count;
};
int read_sentence(struct context *cp) {
char buf[50];
cp->array = NULL;
cp->count = 0;
while (scanf("%49s", buf) == 1) {
// another word was read
char **new_array = realloc(cp->array, (cp->count + 1) * sizeof(*new_array));
char *p = strdup(buf);
if (new_array == NULL || p == NULL) {
// allocation error: free previously allocated memory and return -1
free(p);
if (new_array != NULL) {
cp->array = new_array;
}
while (cp->count > 0) {
free(cp->array[--cp->count]);
}
free(cp->array);
cp->array = NULL;
return -1;
}
cp->array = new_array;
cp->array[cp->count++] = p;
}
return cp->count;
}