C 一个字符串列表-确定我错在哪里

C 一个字符串列表-确定我错在哪里,c,C,这是我需要在算法和数据结构方面解决的问题的一部分,但我无法超越这一点 第一步是加载一组字符串,并使用双指针将它们放入数组中。看起来很清楚。我最初的代码是: int main (void){ char **A, a[50]; int n,i; scanf("%d",&n); A=malloc(n*sizeof(a)); for(i=0;i<n;i++){ fgets(a,sizeof(a),stdin); a[s

这是我需要在算法和数据结构方面解决的问题的一部分,但我无法超越这一点

第一步是加载一组字符串,并使用双指针将它们放入数组中。看起来很清楚。我最初的代码是:

int main (void){
    char **A, a[50];
    int n,i;
    scanf("%d",&n);
    A=malloc(n*sizeof(a));
    for(i=0;i<n;i++){
        fgets(a,sizeof(a),stdin);
        a[sizeof(a)-1]='\0';
        A[i]=a;
        printf("%s",A[i]);
    }
return 0;

}
int main(无效){
字符**A,A[50];
int n,i;
scanf(“%d”和“&n”);
A=malloc(n*sizeof(A));

for(i=0;ifor循环始终将输入字符串存储到数组
a
中,并将相同的地址存储到
a[i]
的每个元素中

我对您的程序做了一些更正:

int main (void){
    char **A, a[50];
    int n,i;
    scanf("%d",&n);
    A=malloc(n*sizeof(char *));
    for(i=0;i<n;i++){
       fgets(a,sizeof(a),stdin);
       A[i]=malloc(strlen(a)+1);
       strcpy(A[i],a);
    }
    return 0;
}
int main(无效){
字符**A,A[50];
int n,i;
scanf(“%d”和“&n”);
A=malloc(n*sizeof(char*));

for(i=0;ifor循环始终将输入字符串存储到数组
a
中,并将相同的地址存储到
a[i]
的每个元素中

我对您的程序做了一些更正:

int main (void){
    char **A, a[50];
    int n,i;
    scanf("%d",&n);
    A=malloc(n*sizeof(char *));
    for(i=0;i<n;i++){
       fgets(a,sizeof(a),stdin);
       A[i]=malloc(strlen(a)+1);
       strcpy(A[i],a);
    }
    return 0;
}
int main(无效){
字符**A,A[50];
int n,i;
scanf(“%d”和“&n”);
A=malloc(n*sizeof(char*));

for(i=0;i
A
是指向
char*
的指针,因此必须将其分配为容纳
n
指针:

A = malloc(n * sizeof(*A));
stdin
读取后,必须按以下方式删除返回行:

a[strcspn(a, "\n")] = '\0';
然后
A
中的每个元素都应该指向一个内存,我们在该内存上复制输入:

A[i] = malloc(strlen(a) + 1);
最后更改此赋值
A[i]=A
,这将使
A
指向
A
,将
A
字符串复制到
A[i]

strncpy(A[i], a, strlen(a) + 1);

其他注意事项是,
scanf
\n
留在
fgets
将要读取的缓冲区中,因此在使用
fgets
读取之前,您必须先使用
\n

int c;
do {
    c = getchar();
} while(c != '\n' && c != EOF);
不要忘记检查
scanf
fgets
的返回值,以了解错误情况:

if (scanf("%d",&n) != 1) {
    fprintf(stderr, "Error while reading n\n");
    return 1;
}
...
if (fgets(a,sizeof(a),stdin) != NULL) {
    fprintf(stderr, "Error while reading input\n");
    return 1;
}
最后,不要忘记释放分配的内存:

for (int i = 0; i < n; i++) {
    free(A[i]);
}
free(A);
for(int i=0;i
A
是指向
char*
的指针,因此必须将其分配为容纳
n
指针:

A = malloc(n * sizeof(*A));
stdin
读取后,必须按以下方式删除返回行:

a[strcspn(a, "\n")] = '\0';
然后
A
中的每个元素都应该指向一个内存,我们在该内存上复制输入:

A[i] = malloc(strlen(a) + 1);
最后更改此赋值
A[i]=A
,这将使
A
指向
A
,将
A
字符串复制到
A[i]

strncpy(A[i], a, strlen(a) + 1);

其他注意事项是,
scanf
\n
留在
fgets
将要读取的缓冲区中,因此在使用
fgets
读取之前,您必须先使用
\n

int c;
do {
    c = getchar();
} while(c != '\n' && c != EOF);
不要忘记检查
scanf
fgets
的返回值,以了解错误情况:

if (scanf("%d",&n) != 1) {
    fprintf(stderr, "Error while reading n\n");
    return 1;
}
...
if (fgets(a,sizeof(a),stdin) != NULL) {
    fprintf(stderr, "Error while reading input\n");
    return 1;
}
最后,不要忘记释放分配的内存:

for (int i = 0; i < n; i++) {
    free(A[i]);
}
free(A);
for(int i=0;i
这是错误的
A=malloc(sizeof(n)*sizeof(A))
,也许您的意思是
A=malloc(n*sizeof(*A))
并始终检查
scanf()
成功了,而不是仅仅相信
n
有一个合适的值。哇,真不敢相信我错过了。但仍然得到了相同的输出。我检查了n,这不是问题。我的意思是你应该确保
scanf()
有效,它与
n
没有直接关系。注意,它仍然是错误的。还有
a[I]=a;
表示所有
a
元素指向完全相同的缓冲区,在每次迭代中都会被覆盖,您必须复制
a
的内容,并在
a[i]中存储指向副本的指针
。我建议你多读一些关于指针如何工作以及它们是什么的内容。介意解释一下,如果扫描后n值正确,为什么scanf不工作吗?谢谢,我已经用指针工作了一段时间,我显然错过了这一点。如果我第一次看到指针,我从不会问这个问题。这是wrong
A=malloc(sizeof(n)*sizeof(A))
,也许您的意思是
A=malloc(n*sizeof(*A))
,并始终检查
scanf()
成功了,而不是仅仅相信
n
有一个合适的值。哇,真不敢相信我错过了。但仍然得到了相同的输出。我检查了n,这不是问题。我的意思是你应该确保
scanf()
有效,它与
n
没有直接关系。注意,它仍然是错误的。还有
a[I]=a;
表示所有
a
元素指向完全相同的缓冲区,在每次迭代中都会被覆盖,您必须复制
a
的内容,并在
a[i]中存储指向副本的指针
。我建议你阅读更多关于指针如何工作以及它们是什么的内容。介意解释一下,如果扫描后n值正确,为什么scanf不工作吗?谢谢,我已经使用指针一段时间了,我显然错过了这一点。如果我第一次看到指针,我从不会问这个问题。
如果(fgets(a,sizeof(a),stdin)!=NULL){
不仅可以处理罕见的输入错误(如消息中所述),而且可以处理更常见的文件结尾。如果查找错误/文件结尾,那么好的代码应该,
},而(c!='\n'&&c!=EOF);
可以防止
EOF上的无限循环。
If(fgets(a,sizeof(a),stdin)!=NULL){
不仅可以处理罕见的输入错误(如消息中所述),还可以处理更常见的文件结尾。如果要查找错误/文件结尾,好的代码应该是,
},而(c!='\n'&&c!=EOF);
可以防止在
EOF
上出现无限循环。