如何定义字符串数组的结尾

时间:2015-03-14 07:14:57

标签: c string multidimensional-array

char数组变满之前结束'\0'数组的方法是将single_str[5] ='\0'; 放在最后,例如 -

char

那么如何以这种方式结束2D {{1}}数组呢?

4 个答案:

答案 0 :(得分:4)

在实践中,您应该在C中避免考虑2D数组。 Stricto sensu,C语言不知道2D数组,只知道数组的数组(固定长度,所有相同大小)或关于指针数组(或聚合或标量数组)。

您可以使用字符串指针数组。 C字符串通常以零字节结束。以下是以const char*字符串结尾的常量数组(常量字符串,即NULL指针)的示例

const char*const arrstr[] = {
   "Hello",
   "Nice",
   "World",
   NULL
};

在我的机器上,sizeof(const char*)为8,因此sizeof(arrstr)为32;而sizeof("Nice")是5。

您可以使用

打印所有数组成员
for (const char*const* p = arrstr; *p; p++) printf("%s\n", *p);

您可以在C99中使用以flexible array member结尾的结构,例如

struct my_string_array_st {
   unsigned len;
   char* arr[]; // array of len pointers */
};

那么你可能有一个构造函数,它构建了像

这样的空内容的字符串数组
struct my_string_array_st* make_string_array(unsigned ln) {
  struct my_string_array_st*p
     = malloc(sizeof(struct my_string_array_st) + len*sizeof(char*));
  if (!p) { perror("malloc"); exit(EXIT_FAILURE); };
  p->len = ln;
  for (unsigned ix=0; ix<ln; ix+) p->arr[ix] = NULL;
  return p; }

然后你决定(这是你要遵循的约定)里面的每个字符串都是用strdup堆分配的 - 所以你里面没有两个别名指针。以下是设置字符串的功能(如果需要,可以释放前一个字符串)

void 
set_string_array(struct my_string_array_st*p, unsigned ix, const char*str) {
  if (!p || ix>=p->len) return;
  free(p->arr[ix]);
  char* s = NULL;
  if (str) {
     s = strdup(str);
     if (!s) { perror("strdup"); exit(EXIT_FAILURE); };
  };
  p->arr[ix] = s;
}

(回想一下你被允许free(3) NULL指针;它是一个无操作的) 这是一个析构函数,释放所有内部字符串。

void destroy_string_array(struct my_string_array_st*p) {
  if (!p) return;
  unsigned l = p->len;
  for (unsigned ix=0; ix<l; ix++) free(p->arr[ix]);
  free (p);
}

当然,这是一个访问函数:

const char* nth_string_array(struct my_string_array_st*p, unsigned ix)
{
  if (!p || ix>=p->len) return NULL;
  return p->arr[ix];
}

答案 1 :(得分:2)

您可以使用空字符串""

#include <stdio.h>

int main(void)
{
    char arr[][3] = {"ab", "cd", ""};
    char (*p)[3] = arr;

    while (**p) { /* while not an empty string */
        printf("%s\n", *p);
        p++;
    } 
    return 0;
}

如果arr可以包含空字符串,则可以使用不可打印的字符,例如ETX(文本结尾):

#include <stdio.h>

int main(void)
{
    char arr[][3] = {"ab", "", "\x03"};
    char (*p)[3] = arr;

    while (**p != '\x03') {
        printf("%s\n", *p);
        p++;
    } 
    return 0;
}

对于不可修改的数组,您可以使用NULL

#include <stdio.h>

int main(void)
{
    char *arr[] = {"ab", "cd", NULL}; /* Read only */
    char **p = arr;

    while (*p) { /* while not NULL */
        printf("%s\n", *p);
        p++;
    } 
    return 0;
}

答案 2 :(得分:2)

您需要定义一个标记值。

作为线性分散数组的哨兵,这可以是任何有效的C-“字符串”,已知在操作期间不会将其用作播放加载值任何数组的元素。

对于分散的数组,NULL也可以用作哨兵。

线性阵列示例

定义哨兵值:

#define END_OF_ARRAY "__EOA__" 

或只是空的“字符串”:

#define END_OF_ARRAY "" 

注意,当与线性阵列一起使用时,标记必须是C-“字符串”!

char array [][8] = {
  "1st",
  "2nd",
  END_OF_ARRAY
}

要检测数组的大小,您可以使用如下函数:

ssize_t get_array_size(const char (*parray)[][8])
{
  ssize_t s = -1;

  if (NULL == parray)
  {
    errno = EINVAL;
  }
  else
  {
    s = 0;

    while (strcmp((*parray)[s], END_OF_ARRAY))
    {
      ++s;
    }
  }

  return s;
}

分散数组的示例

定义哨兵值:

#define END_OF_ARRAY NULL

或者也可能

#define END_OF_ARRAY "__EOA__" 

请注意,通常使用NULL

char * array[] = {
  "1st",
  "2nd",
  END_OF_ARRAY 
}

要检测数组的大小,您可以使用如下函数:

ssize_t get_array_size(const char *** parray)
{
  ssize_t s = -1;

  if (NULL == parray || NULL == *parray)
  {
    errno = EINVAL;
  }
  else
  {
    s = 0;

    while ((*parray)[s] != END_OF_ARRAY)
    {
      ++s;
    }
  }

  return s;
}

<强>用法

对于这两个例子,请这样称呼:

int main(void)
{
  ssize_t result = get_array_size(&array);
  if (-1 == result)
  {
    perror("get_array_size() failed");
  }
  else
  {
    size_t size = result;
    printf("number of elements: %zu\n", size)
  }

  return 0;
}

分散数组的简单方法

定义哨兵值:

#define END_OF_ARRAY NULL

或者也可能

#define END_OF_ARRAY "__EOA__" 

请注意,通常使用NULL

char * array[] = {
  "1st",
  "2nd",
  END_OF_ARRAY 
}

要检测数组的大小,您可以使用如下函数:

ssize_t get_array_size(const char ** parray)
{
  ssize_t s = -1;

  if (NULL == parray)
  {
    errno = EINVAL;
  }
  else
  {
    s = 0;

    while (parray[s] != END_OF_ARRAY)
    {
      ++s;
    }
  }

  return s;
}

<强>用法

注意调用这个更简单的实现时,数组是直接传递的,而不是传递它的地址:

int main(void)
{
  ssize_t result = get_array_size(array);
  if (-1 == result)
  {
    perror("get_array_size() failed");
  }
  else
  {
    size_t size = result;
    printf("number of elements: %zu\n", size)
  }

  return 0;
}

答案 3 :(得分:1)

你可以像这样分配。

  char ar[3][20];
  ar[2][0]='\0';

您可以将null放在您需要的位置。考虑一下,您需要在1th10th列中放置null,就像这样。

  ar[1][10]='\0';

像这样你需要放置null,你可以放置null。