根据用户的输入创建可变数量的字符串变量(C语言)

时间:2016-07-31 08:25:13

标签: c pointers

我想创建一个字符串变量数组,元素的数量取决于用户的输入。例如,如果用户的输入是3,那么他可以输入3个字符串。让我们说“aaa”,“bbb”和“ccc”。它们通过相同的指针存储到char(* ptr)但具有不同的索引。

代码:

int main()
{
    int t;
    scanf("%d", &t);
    getchar();
    char *ptr = malloc(t*sizeof(char));
    int i;

    for(i=0;i<t;i++)
    {
        gets(*(ptr[i]));
    }
    for(i=0;i<t;i++)
    {
        puts(*(ptr[i]));
    }

    return 0;
}

t是元素的数量,* ptr是指向数组的指针。我想在ptr [0],ptr [1]和ptr [2]中存储“aaa”,“bbb”和“ccc”。但是,在gets和puts语句中发现了错误,我无法找到解决方案。有人会帮我吗?谢谢!

3 个答案:

答案 0 :(得分:1)

  • 您不应该使用gets(),它具有不可避免的缓冲区溢出风险,在C99中已弃用并从C11中删除。
  • char中只能存储一个字符。如果要输入的字符串的最大长度是固定的,则可以分配一个元素为char数组的数组。否则,您应该使用char*
  • 数组

试试这个(这是前一种情况):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* the maximum length of strings to be read */
#define STRING_MAX 8

int main(void)
{
    int t;
    if (scanf("%d", &t) != 1)
    {
        fputs("read t error\n", stderr);
        return 1;
    }
    getchar();
    /* +2 for newline and terminating null-character */
    char (*ptr)[STRING_MAX + 2] = malloc(t*sizeof(char[STRING_MAX + 2]));
    if (ptr == NULL)
    {
        perror("malloc");
        return 1;
    }
    int i;

    for(i=0;i<t;i++)
    {
        if (fgets(ptr[i], sizeof(ptr[i]), stdin) == NULL)
        {
            fprintf(stderr, "read ptr[%d] error\n", i);
            return 1;
        }
        /* remove newline character */
        char *lf;
        if ((lf = strchr(ptr[i], '\n')) != NULL) *lf = '\0';
    }
    for(i=0;i<t;i++)
    {
        puts(ptr[i]);
    }

    free(ptr);
    return 0;
}

答案 1 :(得分:0)

你可以使用下面给出的代码,因为字符串数组就像char二维数组,所以使用可以使用指针的指针,当你在运行时通过malloc分配内存时,你需要转换为指向指针字符类型的指针。 / p>

int main()
{
    int t;
    scanf("%d", &t);
    char **ptr = (char **)malloc(t*sizeof(char));
    int i,j;

    for( i=0;i<t;i++)
    {
        scanf("%s",ptr[i]);
    }
    for(i=0;i<t;i++)
    {
        puts(ptr[i]);
    }

    return 0;
}

答案 2 :(得分:0)

这是一个例子,一个干净的,如果稍微内存效率低的方式来处理这个。更高效的内存解决方案将使用一个MAX_LINE_LENGTH字符串并复制到精确长度的字符串..这就是为什么字符串的一个连续内存块是个坏主意。

断言也只是证明需要进行真正检查的地方,因为在生产中,当malloc不执行任何操作时,允许malloc失败。

#include <stdio.h>
#include <malloc.h>
#include <assert.h>

#define MAX_LINE_LENGTH 2048

int
main(void) {

    int tot, i;
    char **strheads; /* A pointer to the start of the char pointers */


    if (scanf("%d\n", &tot) < 1)
        return (1); 

    strheads = malloc(tot * sizeof (char *));
    assert(strheads != NULL);
    /* now we have our series of n pointers to chars,
       but nowhere allocated to put the char strings themselves. */

    for (i = 0; i < tot; i++) {
        strheads[i] = malloc(sizeof (char *) * MAX_LINE_LENGTH);
        assert(strheads[i] != NULL);
        /* now we have a place to put the i'th string,
           pointed to by pointer strheads[i] */
        (void) fgets(strheads[i], MAX_LINE_LENGTH, stdin);
    }
    (void) printf("back at ya:\n");
    for (i = 0; i < tot; i++) {
        fputs(strheads[i], stdout);
        free(strheads[i]); /* goodbye, i'th string */
    }

    free(strheads); /* goodbye, char pointers [0...tot] */

    return (0);
}