在char
数组变满之前结束'\0'
数组的方法是将single_str[5] ='\0';
放在最后,例如 -
char
那么如何以这种方式结束2D {{1}}数组呢?
答案 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放在您需要的位置。考虑一下,您需要在1th
行10th
列中放置null,就像这样。
ar[1][10]='\0';
像这样你需要放置null,你可以放置null。