C中的string是一个连续的非零字节序列,后面跟着零字节(以空值结尾的字节'\0'
).
char
是表示单个字符的类型-恰好是byte.
char strings_array[n];
是一个包含n个字节的variable-length array,实际上只适合容纳一个string,字符串长度最多为n - 1个字符(必须始终为空终止字节留出空间).
(Note: if the user is clever enough to enter a value less than one, this program invokes 100 by declaring an array whose size is less than one. Additionally, the user may enter a very large value, potentially exhausting your programs 101. It is a good idea to validate user input.)
因此,要拥有多个字符串数组,您必须真正创建一个数组数组(或指针数组,但现在让我们重点介绍前者).
char strings[n][16];
将是由n个数组组成的数组,每个数组16个字节.它将能够容纳n个字符串(每个字符串的最大长度为15).
这有时被称为two-dimensional数组,这使得它很容易可视化.假设是n=4
,那么这个数组可以如下所示,其中每cell是一个字节:
[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
如果您要求用户填充前两个sub-arrays(如scanf("%15s", &strings[i])
),并输入hello
,然后输入stackoverflow
,则数组将如下所示:
[ h][ e][ l][ l][ o][\0][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ s][ t][ a][ c][ k][ o][ v][ e][ r][ f][ l][ o][ w][\0][ ][ ]
[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
以下是一个实用示例:
#include <stdio.h>
#include <stdlib.h>
static void fatal(const char *msg)
{
fprintf(stderr, "%s\n", msg);
exit(EXIT_FAILURE);
}
int main(void)
{
int n;
printf("How many strings do you want to enter? ");
if (1 != scanf("%d", &n) || 1 > n || n > 32)
fatal("Invalid size specified.");
char strings[n][64];
for (int i = 0; i < n; i++) {
printf("Please enter string #%d: ", i + 1);
if (1 != scanf("%63s", strings[i]))
fatal("Invalid string input.");
}
for (int i = 0; i < n; i++)
puts(strings[i]);
}
请注意,我们总是判断返回值scanf
是成功conversions的预期数量(%d
是one转换说明符,因此如果返回值不是1
,则发生错误).
另外请注意,我们通过将maximum field-width指定为%63s
来限制scanf
可以使用%s
读取的数据量,这是我们的数组可以容纳的最长字符串(数组的大小减go 1,为空终止字节留出空间).在不指定此限制的情况下,scanf
可以读取的数据多于数组可以存储的数据,从而导致buffer overflow.
程序I/O:
How many strings do you want to enter? 2
Please enter string #1: hello
Please enter string #2: stackoverflow
hello
stackoverflow