如何在 C 中使用 POINTERS 创建一个二维字符数组?
How can I create a 2D array of chars with POINTERS in C?
我正在尝试创建一个程序,用户输入项目(行)的数量并为每个项目指定一个名称(scanf),最多 30 个字符。
我想用指针的指针创建这段代码,一旦我在 C 上学习它。
我在编写代码时遇到一些困难。
Draft of the 2D array.
代码片段:
PS: #define MAX 31
char **items = NULL, *columns = NULL, name[MAX];
int rows, aux_rows;
printf("\nNumber of items:\n");
scanf("%d", &rows);
items = (char **) malloc(rows * sizeof(char*));
for (aux_rows = 0; aux_rows < rows; aux_rows++){
columns[aux_rows] = (char *) malloc(MAX * sizeof(char));
}
for (aux_rows = 0; aux_rows < rows; aux_rows++){
printf("\nName of item %d:\n", (aux_rows + 1));
scanf("%s", name);
*items[aux_rows] = name;
}
items
被分配而不是 columns
。并使用strcpy
复制字符。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 31
int main()
{
char **items = NULL, *columns = NULL, name[MAX];
int rows, aux_rows;
printf("\nNumber of items:\n");
scanf("%d", &rows);
items = (char **)malloc(rows * sizeof(char *));
for (aux_rows = 0; aux_rows < rows; aux_rows++)
{
items[aux_rows] = malloc(MAX * sizeof(char));
}
for (aux_rows = 0; aux_rows < rows; aux_rows++)
{
printf("\nName of item %d:\n", (aux_rows + 1));
scanf("%s", name);
strcpy(items[aux_rows], name);
}
return 0;
}
$ gcc array2d.c
$ ./a.out
Number of items:
2
Name of item 1:
Hello
Name of item 2:
World!
$
*items[aux_rows] = name;
有两点是错误的。
*
和 []
都取消引用它们的一元操作数。如果 items
是 char **
,items[n]
是 char *
,*items[n]
是 char
。
这会尝试将数组分配给每个缓冲区的第一个元素。
其次,不能通过赋值复制数组。使用 strcpy
将字符串从一个缓冲区复制到另一个缓冲区。
就是说,您可以直接将字符串读入 pre-allocated 缓冲区,并取消临时缓冲区。
这一行,
columns[aux_rows] = (char *) malloc(MAX * sizeof(char));
columns
应该是 items
.
一些注意事项:
sizeof (char)
保证为 1
。它的使用是多余的。
C中malloc
should not be castreturn
malloc
可能会失败。 scanf
可能会失败。您应该养成不忽略 return 值的习惯。
scanf("%s", ...)
等同于 dangerous as gets
。至少,使用 field-width 说明符 来限制输入(应该是缓冲区的大小减一)。
char foo[128];
if (1 != scanf("%127s", foo))
/* handle error */;
请注意,使用 %s
将输入限制为不包含任何空格。 scanf
通常是 terrible tool,考虑使用 fgets
.
的基于行的方法
话虽如此,要使其合理安全的最小更改:
#include <stdio.h>
#include <stdlib.h>
#define MAX 31
void die(const char *msg)
{
fprintf(stderr, "%s\n", msg);
exit(EXIT_FAILURE);
}
int main(void)
{
size_t rows;
printf("Number of items: ");
if (1 != scanf("%zu", &rows))
die("Failed to read input.");
char **items = malloc(sizeof *items * rows);
if (!items)
die("Failed to allocate memory.");
for (size_t i = 0; i < rows; i++) {
if (!(items[i] = malloc(MAX)))
die("Failed to allocate row.");
printf("Name of item %zu: ", i + 1);
if (1 != scanf("%30s", items[i]))
die("Failed to read item input.");
}
for (size_t i = 0; i < rows; i++) {
puts(items[i]);
free(items[i]);
}
}
我正在尝试创建一个程序,用户输入项目(行)的数量并为每个项目指定一个名称(scanf),最多 30 个字符。
我想用指针的指针创建这段代码,一旦我在 C 上学习它。
我在编写代码时遇到一些困难。
Draft of the 2D array.
代码片段:
PS: #define MAX 31
char **items = NULL, *columns = NULL, name[MAX];
int rows, aux_rows;
printf("\nNumber of items:\n");
scanf("%d", &rows);
items = (char **) malloc(rows * sizeof(char*));
for (aux_rows = 0; aux_rows < rows; aux_rows++){
columns[aux_rows] = (char *) malloc(MAX * sizeof(char));
}
for (aux_rows = 0; aux_rows < rows; aux_rows++){
printf("\nName of item %d:\n", (aux_rows + 1));
scanf("%s", name);
*items[aux_rows] = name;
}
items
被分配而不是 columns
。并使用strcpy
复制字符。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 31
int main()
{
char **items = NULL, *columns = NULL, name[MAX];
int rows, aux_rows;
printf("\nNumber of items:\n");
scanf("%d", &rows);
items = (char **)malloc(rows * sizeof(char *));
for (aux_rows = 0; aux_rows < rows; aux_rows++)
{
items[aux_rows] = malloc(MAX * sizeof(char));
}
for (aux_rows = 0; aux_rows < rows; aux_rows++)
{
printf("\nName of item %d:\n", (aux_rows + 1));
scanf("%s", name);
strcpy(items[aux_rows], name);
}
return 0;
}
$ gcc array2d.c
$ ./a.out
Number of items:
2
Name of item 1:
Hello
Name of item 2:
World!
$
*items[aux_rows] = name;
有两点是错误的。
*
和 []
都取消引用它们的一元操作数。如果 items
是 char **
,items[n]
是 char *
,*items[n]
是 char
。
这会尝试将数组分配给每个缓冲区的第一个元素。
其次,不能通过赋值复制数组。使用 strcpy
将字符串从一个缓冲区复制到另一个缓冲区。
就是说,您可以直接将字符串读入 pre-allocated 缓冲区,并取消临时缓冲区。
这一行,
columns[aux_rows] = (char *) malloc(MAX * sizeof(char));
columns
应该是 items
.
一些注意事项:
sizeof (char)
保证为 1
。它的使用是多余的。
C中malloc
should not be castreturn
malloc
可能会失败。 scanf
可能会失败。您应该养成不忽略 return 值的习惯。
scanf("%s", ...)
等同于 dangerous as gets
。至少,使用 field-width 说明符 来限制输入(应该是缓冲区的大小减一)。
char foo[128];
if (1 != scanf("%127s", foo))
/* handle error */;
请注意,使用 %s
将输入限制为不包含任何空格。 scanf
通常是 terrible tool,考虑使用 fgets
.
话虽如此,要使其合理安全的最小更改:
#include <stdio.h>
#include <stdlib.h>
#define MAX 31
void die(const char *msg)
{
fprintf(stderr, "%s\n", msg);
exit(EXIT_FAILURE);
}
int main(void)
{
size_t rows;
printf("Number of items: ");
if (1 != scanf("%zu", &rows))
die("Failed to read input.");
char **items = malloc(sizeof *items * rows);
if (!items)
die("Failed to allocate memory.");
for (size_t i = 0; i < rows; i++) {
if (!(items[i] = malloc(MAX)))
die("Failed to allocate row.");
printf("Name of item %zu: ", i + 1);
if (1 != scanf("%30s", items[i]))
die("Failed to read item input.");
}
for (size_t i = 0; i < rows; i++) {
puts(items[i]);
free(items[i]);
}
}