简体   繁体   English

如何在 C 中使用 POINTERS 创建一个二维字符数组?

[英]How can I create a 2D array of chars with POINTERS in C?

I'm trying to create a program which the user inputs the number of items (rows) and give each one of them a name (scanf) with the max of 30 characters.我正在尝试创建一个程序,用户输入项目数(行)并为每个项目指定一个名称(scanf),最多 30 个字符。

I want to create this code with pointers of pointers, once that I'm learning this on C.一旦我在 C 上学习这个,我想用指针的指针创建这个代码。

I'm having some difficulties with the code.我在代码方面遇到了一些困难。

Draft of the 2D array.二维数组的草图。

Code snippet:代码片段:

PS: #define MAX 31 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 was allocated and not columns .分配了items而不是columns And use strcpy to copy the characters.并使用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;

is wrong on two counts.在两个方面是错误的。

Both * and [] dereference their unary operand. *[]都取消引用它们的一元操作数。 If items is a char ** , items[n] is a char * , and *items[n] is a char .如果itemschar **items[n]char **items[n]char

This attempts to assign an array to the first element of each buffer.这试图将一个数组分配给每个缓冲区的第一个元素。

Secondly, arrays cannot be copied by assignment.其次,数组不能通过赋值来复制。 Use strcpy to copy strings from one buffer to another.使用strcpy将字符串从一个缓冲区复制到另一个缓冲区。

That said, you could simply read your strings directly into the pre-allocated buffers, and do away with the temporary buffer.也就是说,您可以简单地将字符串直接读取到预先分配的缓冲区中,并取消临时缓冲区。


In this line,在这一行中,

columns[aux_rows] = (char *) malloc(MAX * sizeof(char));

columns should be items . columns应该是items


Some things of note:一些注意事项:

sizeof (char) is guaranteed to be 1 . sizeof (char)保证为1 Its use is superfluous.它的使用是多余的。

The return of malloc should not be cast in C. malloc的返回不应在 C 中强制转换。

malloc can fail. malloc可能会失败。 scanf can fail. scanf可能会失败。 You should get in the habit of not ignoring return values.你应该养成不忽略返回值的习惯。

scanf("%s", ...) is as dangerous as gets . scanf("%s", ...)gets一样危险 At a minimum, use field-width specifiers to limit input (should be the size of your buffer minus one).至少,使用字段宽度说明符来限制输入(应该是缓冲区的大小减一)。

char foo[128];
if (1 != scanf("%127s", foo))
    /* handle error */;

Note that using the %s limits input to not contain any whitespace.请注意,使用%s限制输入不包含任何空格。 scanf in general is a terrible tool , consider a line based approach using fgets . scanf通常是一个糟糕的工具,考虑使用fgets的基于行的方法。

With that said, the minimum changes to make this reasonably safe:话虽如此,使这合理安全的最小更改:

#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]);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM