string [,]在C

时间:2016-01-07 15:29:27

标签: c# c arrays

在C#中,如果我要创建一个字符串数组数组,那就很容易:

string[,] array = new string[50,7];

我如何在C中这样做?我明白我应该使用指针,但我提出的似乎并不正常。

char *array[50][7];

请注意,我不打算将元素设置为常量值,我需要能够通过使用scanf()函数或仅使用{=函数再次访问它们/在程序中设置它们{1}}如果可能的话。实现这一目标的最简单方法是什么?

编辑:我在这里做错了吗?以下非常简单的示例使程序崩溃:

char *username;

printf("Username: ");
scanf("%s", &username);

array[0][0] = malloc(strlen(username) + 1);
strcpy(array[0][0], username);

事实上,我已经添加了对stdlib.h

的引用

4 个答案:

答案 0 :(得分:3)

没有简单的方法:)因为C没有高级别的字符串类,至少没有调用一些非标准的库。

为了保持灵活性,您确实需要一个指针char *array[50][7];的2D数组,其中每个指针都设置为指向实际的字符串。在创建字符串时,您必须使用malloc()分配足够的内存来保存它,加上null终止符。例如:

array[x][y] = malloc(strlen(the_string) + 1);
assert(array[x][y] != NULL);

无法使用=赋值运算符复制C中的字符串,因此在分配内存后,必须使用strcpy将字符串复制到分配的内存区域。

strcpy(array[x][y], the_string);

答案 1 :(得分:1)

阵列没问题。问题可能来自字符串。 C'字符串'的级别非常低,无法与C#字符串进行比较。您必须手动为它们分配和释放空间。如果您打算在它们上使用scanf,则可以为每个缓冲区分配一个缓冲区,但如果找到的字符串长于缓冲区,则会遇到问题。您可以使用'='指定它们,但前提是您处理旧值的释放。也许你可以检查一下像'glib'这样的库,为你做一些工作。

答案 2 :(得分:1)

以下代码崩溃,因为代码尝试将scanf()输入保存到username指向的位置,但username未初始化。

char *username;
scanf("%s", &username);  // bad

相反,可以使用

char username[100];
scanf("%99s", username);

或更好

char username[100];
fgets(username, sizeof username, stdin);
username[strcspn(username, "\n")] = '\0';  // lop off potential \n

看起来OP想要一个50 x 7指向C字符串的指针数组,就像string[,] array = new string[50,7];

一样

回想一下,在C中,字符串本身就是一个以空字符结尾的字符数组

#include <stdlib.h>
typedef char *a50_7_T[50][7];

a50_7_T *a50_7_alloc(void) {
  a50_7_T *a = malloc(sizeof *a);
  for (int i=0; i<50; i++) {
    for (int j=0; j<7; j++) {
      (*a)[i][j] = NULL;  // or whatever OP wants as initial state
    }
  }
  return a;
}

void a50_7_free(a50_7_T *a) {
  for (int i=0; i<50; i++) {
    for (int j=0; j<7; j++) {
      free((*a)[i][j]);
    }
  }
  free(a);
}

// Sample usage code
#include <string.h>
void foo(void) {
  a50_7_T *a = a50_7_alloc();
  printf("Size %zu\n", sizeof *a);   // e.g. "Size 1400"
  (*a)[0][0] = strcpy(malloc(6), "Hello");
  a50_7_free(a);
}

OTOH如果OP希望在声明中创建数组,OP在正确的轨道上做了什么。

//                   Initialize all to zeros, (NULL)
char *array[50][7] = { 0 };
...
array[0][0] = strcpy(malloc(6), "Hello");
...
free(array[0][0]);

答案 3 :(得分:0)

嗯,你必须决定C#根本没有给你一个选择的两件事(或者至少,强烈推荐标准的非常):

  1. 您想如何表示二维数组?

    您可以选择

    • 一维数组和显式指针算法
    • 指向具有一个固定维度的二维数组的指针
    • 指向1维数组指针的1维数组的指针。
  2. 您想如何表示字符串?

    • 决定代码单元:Etc..(希望是8位),charwchar16_twchar32_t
    • 计算字符串或0终止?
    • 在固定大小的缓冲区中还是动态分配的?