如何动态分配内存空间为一个字符串,并得到用户该字符串?

问题描述 投票:42回答:11

我想用C程序从用户读取输入。我不想使用数组一样,

char names[50];

因为如果用户给出长度10的字符串,然后将剩余的空间被浪费了。

如果我使用字符指针一样,

char *names;

然后我需要在这样的分配内存,

names = (char *)malloc(20 * sizeof(char));

在这种情况下,有足够空间浪费的可能性。

所以,我需要的是动态分配内存的一个字符串,它是完全一样的字符串的长度。

让我们假设,

如果用户输入是"stackoverflow",则所分配的存储器应该是14(即字符串的长度= 13和用于“\ 0” 1个额外的空间)的。

我怎么能做到这一点?

c string memory-management malloc dynamic
11个回答
42
投票

在同一时间(使用getc(stdin))读取一个字符和成长的字符串(realloc),当您去。

下面是我写了前一段时间的函数。注意它仅用于文本输入。

char *getln()
{
    char *line = NULL, *tmp = NULL;
    size_t size = 0, index = 0;
    int ch = EOF;

    while (ch) {
        ch = getc(stdin);

        /* Check if we need to stop. */
        if (ch == EOF || ch == '\n')
            ch = 0;

        /* Check if we need to expand. */
        if (size <= index) {
            size += CHUNK;
            tmp = realloc(line, size);
            if (!tmp) {
                free(line);
                line = NULL;
                break;
            }
            line = tmp;
        }

        /* Actually store the thing. */
        line[index++] = ch;
    }

    return line;
}

0
投票

这是更简单的方法

char *in_str;
in_str=(char *)malloc(512000 * sizeof(char));
scanf("\n%[^\n]",in_str);

0
投票

realloc的是一个非常昂贵的行动......这是我收到的字符串的方式,realloc的比例不是1:1:

char* getAString()
{    
    //define two indexes, one for logical size, other for physical
    int logSize = 0, phySize = 1;  
    char *res, c;

    res = (char *)malloc(sizeof(char));

    //get a char from user, first time outside the loop
    c = getchar();

    //define the condition to stop receiving data
    while(c != '\n')
    {
        if(logSize == phySize)
        {
            phySize *= 2;
            res = (char *)realloc(res, sizeof(char) * phySize);
        }
        res[logSize++] = c;
        c = getchar();
    }
    //here we diminish string to actual logical size, plus one for \0
    res = (char *)realloc(res, sizeof(char *) * (logSize + 1));
    res[logSize] = '\0';
    return res;
}

6
投票

你可以有10个元素开始了一个数组。通过文字阅读输入字符。如果越过,realloc的另一个5个。不是最好的,但您可以稍后再释放其他空间。


5
投票

如果应该的备用内存,通过炭阅读char和每一次的realloc。性能会死,但是你会放过这10个字节。

另一种很好的折衷是读取一个函数(使用一个局部变量)然后复制。因此,最大的缓冲区将被功能作用域。


5
投票

您还可以使用正则表达式,比如下面的代码:

char *names
scanf("%m[^\n]", &names)

将获得从标准输入整条生产线,分配的,它需要的空间动态量。在此之后,当然,你必须释放names


3
投票

下面是用于创建动态字符串的代码:

void main()
{
  char *str, c;
  int i = 0, j = 1;

  str = (char*)malloc(sizeof(char));

  printf("Enter String : ");

  while (c != '\n') {
    // read the input from keyboard standard input
    c = getc(stdin);

    // re-allocate (resize) memory for character read to be stored
    str = (char*)realloc(str, j * sizeof(char));

    // store read character by making pointer point to c
    str[i] = c;

    i++;
    j++;
  }

  str[i] = '\0'; // at the end append null character to mark end of string

  printf("\nThe entered string is : %s", str);

  free(str); // important step the pointer declared must be made free
}

1
投票
char* load_string()
 {

char* string = (char*) malloc(sizeof(char));
*string = '\0';

int key;
int sizer = 2;

char sup[2] = {'\0'};

while( (key = getc(stdin)) != '\n')
{
    string = realloc(string,sizer * sizeof(char));
    sup[0] = (char) key;
    strcat(string,sup);
    sizer++

}
return string;

}

int main()
  {
char* str;
str = load_string();

return 0;
  }

0
投票

下面是我写的执行相同功能的片段。

此代码是一个类似于通过Kunal Wadhwa写的。

char *dynamicCharString()
{
char *str, c;
int i;
str = (char*)malloc(1*sizeof(char));

while(c = getc(stdin),c!='\n')
{
    str[i] = c;
    i++;
    realloc(str,i*sizeof(char));
}
str[i] = '\0';
return str;
}

0
投票

首先,定义一个新的功能来读取(根据您输入的结构)输入并存储串,这意味着在使用堆叠中的存储器中。设置字符串的长度足够您的输入。

其次,使用strlen测量字符串的确切长度使用之前存储,并且malloc到在堆,其长度由strlen定义分配内存。的代码如下所示。

int strLength = strlen(strInStack);
if (strLength == 0) {
    printf("\"strInStack\" is empty.\n");
}
else {
    char *strInHeap = (char *)malloc((strLength+1) * sizeof(char));
    strcpy(strInHeap, strInStack);
}
return strInHeap;

最后,复制strInStack的价值使用strInHeapstrcpy,并返回指针strInHeap。因为它只有在这个子功能退出strInStack将被自动释放。


0
投票

这是一个功能片段我写扫描的用户输入的字符串,然后该字符串存储相同尺寸的用户输入的阵列上。请注意,我初始化J确定的2的值可以存储“\ 0”字符。

char* dynamicstring() {
    char *str = NULL;
    int i = 0, j = 2, c;
    str = (char*)malloc(sizeof(char));
    //error checking
    if (str == NULL) {
        printf("Error allocating memory\n");
        exit(EXIT_FAILURE);
    }

    while((c = getc(stdin)) && c != '\n')
    {
        str[i] = c;
        str = realloc(str,j*sizeof(char));
        //error checking
        if (str == NULL) {
            printf("Error allocating memory\n");
            free(str);
            exit(EXIT_FAILURE);
        }

        i++;
        j++;
    }
    str[i] = '\0';
    return str;
}

在main(),你可以声明另一个字符*变量来存储dynamicstring的返回值(),然后释放一个字符*变量,当你使用它来完成。

© www.soinside.com 2019 - 2024. All rights reserved.