此代码不扫描整个数组。它在中间打破
# include<stdio.h>
# include<stdlib.h>
int** create(int m)
{
char **a;
int i;
a=(char**)malloc(sizeof(char*)*m);
for(i=0; i<m; i++)
*(a+i)=(char*)malloc(sizeof(char)*m);
return a;
}
int main()
{
int i,j,n;
char **a;
scanf("%d",&n);
a = create(n);
for(i=0;i<n;i++)
for(j=0;j<n;j++)
scanf("%c",*(a+i)+j);
printf("Output is \n");
for(i=0;i<4;i++)
for(j=0;j<4;j++)
printf("%c",*(*(a+i)+j));
return 0;
}
给出的输入是n = 4 它扫描两行,然后打印回两行...... 这是输出的屏幕截图 Output ScreenShot
答案 0 :(得分:1)
您的代码中存在大量问题。当我们来到他们面前时,我们将解决他们。首先,虽然您可以在单个函数中为m
指针和m
个指针分配存储空间,但它会使该函数在使用中非常有限。最好使用一个分配给定字节数的函数,并为您进行错误检查(如果你愿意,可以检查错误malloc
),例如
void *create (size_t s)
{
void *memptr = calloc (1, s);
if (!memptr) {
fprintf (stderr, "create() error: virtual memory exhausted.\n");
exit (EXIT_FAILURE);
}
return memptr;
}
(注意: calloc
用于初始化所有字符和指针0, NULL
,以防止在未输入所有字符的情况下从未初始化的值读取。)
您的变量类型int
很好,但不是最优的,因为malloc
期望size_t
(并且因为数组索引不能为负数,所以对所有人来说更有意义)
size_t i, j, n = 0;
char **a = NULL;
您必须验证每次scanf
的使用,否则,您无法知道您的代码是否正在从此处开始处理垃圾。始终,始终验证用户输入。此外,在用户按 [Enter] 后,您将在输入缓冲区('\n'
)中留下stdin
在为第一个字符调用scanf
之前进行说明。 (字符输入的更好选择是getchar()
)。您可以使用'*'
分配抑制运算符来scanf
到 read&amp;丢弃尾随'\n'
。 e.g。
printf ("\n enter number of pointers to create: ");
if (scanf (" %zu%*c", &n) != 1) { /* strip \n from input buf */
fprintf (stderr, "error: invalid unput.\n");
return 1;
}
接下来,由于create
是一个有用的分配函数,它将为每个调用分配一个内存块,因此您只需为所需的每个内存块调用create
。 e.g。
a = create (n * sizeof *a); /* allocate mem for n pointers */
for (i = 0; i < n; i++)
a[i] = create (n); /* allocate n chars per-ponter */
阅读您的数据会带来您在上面'\n'
时遇到的同样问题。您需要一些方法对其进行说明并将其删除,或scanf ("%c", ...)
将很乐意接受'\n'
作为您的下一个输入。您可以在一行中输入所有字符,或者您可以实际检查是否存在'\n'
并忽略它,如下所示:
printf (" enter (%zu x %zu) chars ('\\n' ignored)\n", n, n);
for (i = 0; i < n; i++) { /* read (n x n) chars into 'a' */
int c;
for (j = 0; j < n && (c = getchar()) != EOF;) {
if (c != '\n') /* if c is not '\n' add to 'a' */
*(*(a + i) + j++) = c;
}
if (c == EOF) break; /* bail if EOF encountered */
}
最后,在你动态分配内存的任何代码中,你有2个职责关于分配的任何内存块:(1)总是保留一个指向起始地址的指针对于内存块,(2)当不再需要时,它可以释放。完成已分配的内存后,free
。 e.g。
for (i = 0; i < n; i++) /* free all allocated memory */
free (*(a + i));
free (a);
return 0;
}
将拼图的所有部分组合在一起,您可以编写类似于以下内容的代码:
# include <stdio.h>
# include <stdlib.h>
void *create (size_t s)
{
void *memptr = calloc (1, s);
if (!memptr) {
fprintf (stderr, "create() error: virtual memory exhausted.\n");
exit (EXIT_FAILURE);
}
return memptr;
}
int main (void ) {
size_t i, j, n = 0;
char **a = NULL;
printf ("\n enter number of pointers to create: ");
if (scanf (" %zu%*c", &n) != 1) { /* strip \n from input buf */
fprintf (stderr, "error: invalid unput.\n");
return 1;
}
a = create (n * sizeof *a); /* allocate mem for n pointers */
for (i = 0; i < n; i++)
a[i] = create (n); /* allocate n chars per-ponter */
printf (" enter (%zu x %zu) chars ('\\n' ignored)\n", n, n);
for (i = 0; i < n; i++) { /* read (n x n) chars into 'a' */
int c;
for (j = 0; j < n && (c = getchar()) != EOF;) {
if (c != '\n') /* if c is not '\n' add to 'a' */
*(*(a + i) + j++) = c;
}
if (c == EOF) break;
}
printf ("\n output is \n");
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++)
putchar (*(*(a + i) + j));
putchar ('\n');
}
for (i = 0; i < n; i++) /* free all allocated memory */
free (*(a + i));
free (a);
return 0;
}
示例使用/输出
将所有字符输入为单行输入
$ ./bin/create
enter number of pointers to create: 4
enter (4 x 4) chars ('\n' ignored)
catsdogsmiceflea
output is
cats
dogs
mice
flea
每行输入n
个字符
$ ./bin/create
enter number of pointers to create: 4
enter (4 x 4) chars ('\n' ignored)
cats
dogs
mice
flea
output is
cats
dogs
mice
flea
内存使用/错误检查
必须使用内存错误检查程序,以确保您没有在已分配的内存块之外/之外写入,尝试读取或基于未初始化的值跳转,最后确认您已拥有释放了你分配的所有内存。
$ valgrind ./bin/create
==7034== Memcheck, a memory error detector
==7034== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==7034== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==7034== Command: ./bin/create
==7034==
enter number of pointers to create: 4
enter (4 x 4) chars ('\n' ignored)
cats
dogs
mice
flea
output is
cats
dogs
mice
flea
==7034==
==7034== HEAP SUMMARY:
==7034== in use at exit: 0 bytes in 0 blocks
==7034== total heap usage: 5 allocs, 5 frees, 48 bytes allocated
==7034==
==7034== All heap blocks were freed -- no leaks are possible
==7034==
==7034== For counts of detected and suppressed errors, rerun with: -v
==7034== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 1 from 1)
始终确认释放所有堆块 - 不可能泄漏并且同样重要错误摘要:0个上下文中的0个错误。
查看答案,如果您有任何问题,请告诉我。
答案 1 :(得分:0)
scanf("%c",*(a+i)+j);
当i
为1且j
为2时,此访问哪个元素?
当i
为2且j
为1时呢?
答案 2 :(得分:-1)
a是一个char并且不能添加到一个整数,即使它包含一个数字,所以你必须将它转换为一个整数来使用+ i,这样做你可以使用atoi()函数并包含string.h库。
atoi()接受一个字符串作为输入,但如果字符串包含字符串必须包含数字的字符,则不能正常工作。
#include <string.h>
#include <stdio.h>
int main()
{
char a;
int x;
a='4';
x=atoi(a);//now you can use x to add it to an integer
}
因为bob说a是一个char而且函数的返回是int所以你不能使用return a;