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

根据用户的输入创建字符串变量的变量数(C语言),c,pointers,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++) {

我想创建一个字符串变量数组,元素的数量取决于用户的输入。例如,如果用户的输入是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语句中发现了错误,我无法找到解决方案。有人能帮我一下吗?谢谢大家!

您不应该使用gets,它有不可避免的缓冲区溢出风险,C99中不推荐使用gets,C11中删除了gets。 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;
}

您可以使用下面给出的代码,因为字符串数组类似于char2d数组,所以use可以使用指针的指针,当您在运行时通过malloc分配内存时,您需要转换为指针到指针的字符类型

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;
}

下面是一个示例,它是一种干净但内存效率稍低的处理方法。更节省内存的解决方案是使用一个最大行长度的字符串,并复制到精确长度的字符串。。这就是为什么一个连续的字符串内存块是个坏主意

这些断言还只是演示了在什么地方需要进行真正的检查,因为在断言不起任何作用的情况下,允许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);
}

请分享错误的描述。它们由指向char*ptr的相同指针存储,但索引不同。这是什么意思?您正在处理字符串,但为单个字符分配/递增。@ImranAli错误为test.c:在函数“main”中:test.c:15:8:错误:一元数“”的无效类型参数具有“int”test.c:19:8:错误:一元数“”的无效类型参数具有gets和语句的“int”puts@MikeCAT我是对不起,我的英语不好,所以可能解释得不好。我的意思是,我希望通过使用不同的index0,1,2,3。。。。。。要访问它们,谢谢MikeCAT!我发现你的代码可以解决这个问题。但是,有一些部分我不懂,因为我对C的了解不够。第一部分:定义字符串\u MAX 8您定义要读取的字符串的最大长度为8。但是,当我为t输入2,为2个字符串输入aaaaaa 8和aaaaaa 9时,我发现输出将是aaaaaa 8和aaaaaaaa 9。第二个字符串已超过最大长度8,但仍可正确输出。第二部分:char ptr[string_max+2]=malloctsizeofchar[string_max+2];为什么我们需要在sizeofchar中包含[String_MAX+2],而不仅仅是sizeofchar?第三部分:如果ptr==NULL{perromalloc;return 1;},我想知道这个错误信号何时会出现?当我被要求输入字符串时,我不会输入任何东西,只要按enter键,输出仍然是enter而不是malloc。第四部分:char*lf;如果lf=strchrptr[i],“\n”!=NULL*lf='\0';我不明白这两行是什么意思。莫希特·普拉卡什,谢谢你的回复。但是我发现你的解决方案有一些问题。在我为t输入2之后,我为第一个字符串输入aaa。然后,一个分段错误core dumped被告知,这使得程序被确定。该代码使用通过malloc分配的缓冲区中的值调用未定义的行为,而未初始化的值是不确定的。如果sizeofchar*>sizeofchar,则另一个未定义的行为可以通过超出范围的访问调用,这是典型的。