Cprogramming 简明教程
Strings in C
Strings in C
string in C 是 char 类型的一维数组,数组中的最后一个字符是表示为 '\0' 的“空字符”。因此,C 中的一个字符串可以定义为 char 类型值的一个以 null 结尾的序列。
Creating a String in C
让我们创建一个字符串“Hello”。它包含五个 char 值。在 C 中,char 类型的文字表示法使用单引号符号 − 例如 'H'。这五个字母放在单引号中,后跟用 '\0' 表示的空字符,被分配给一个 char 类型的数组。该数组的大小为五个字符加上空字符 − 六个。
Initializing String Without Specifying Size
C 允许你在不声明大小的情况下初始化一个数组,在这种情况下编译器会自动确定数组大小。
Example
char greeting[] = {'H', 'e', 'l', 'l', 'o', '\0'};
在内存中创建的数组可以按如下方式进行概要说明:
如果字符串没有以“\0”结尾,则会导致行为不确定。
Note: 字符串的长度不包括空字符。库函数 strlen() 返回此字符串的长度为 5。
Loop Through a String
您可以遍历一个字符串(字符数组)以使用 for loop 或任何其他 loop statements 访问和操作字符串的每个字符。
Printing a String (Using %s Format Specifier)
Example
“%s”说明符告诉函数遍历数组,直到它遇到空终止符 (\0) 并打印每个字符。这有效地打印了字符数组表示的整个字符串,而无需使用循环。
#include <stdio.h>
int main (){
char greeting[] = {'H', 'e', 'l', 'l', 'o', '\0'};
printf("Greeting message: %s\n", greeting );
return 0;
}
它将生成如下输出:
Greeting message: Hello
您可以声明一个超大数组并分配较少数量的字符,对此 C compiler 没有问题。但是,如果该大小小于初始化中的字符,则输出中可能会有垃圾值。
char greeting[3] = {'H', 'e', 'l', 'l', 'o', '\0'};
printf("%s", greeting);
Constructing a String using Double Quotes
C 允许您通过在双引号中括住字符来构造字符串,而不用在单引号中构造单个 char 值的 char 数组,并使用“\0”作为最后一个元素。这种初始化字符串的方法更加方便,因为编译器会自动将“\0”添加为最后一个字符。
String Input Using scanf()
声明空终止字符串会造成困难,如果你想让用户输入一个字符串。您可以借助一个 for 循环,一次接收一个字符来存储在数组的每个下标中 −
Example
在下面的示例中,您可以使用 scanf() function 输入一个字符串,在输入特定字符后(在以下示例中为 5 个),我们分配空值 ( '\0' ) 来结束字符串。
printf("Starting typing... ");
for (i = 0; i < 5; i++) {
scanf("%c", &greeting[i]);
}
// Assign NULL manually
greeting[i] = '\0';
// Printing the string
printf("Value of greeting: %s\n", greeting);
运行代码并检查其输出:
Starting typing... Hello
Value of greeting: Hello
Example
输入 "\0"(空字符串)是不可能的,因为它是一个不可打印的字符。要克服此问题,在 scanf() 语句中使用 "%s" 格式说明符 −
#include <stdio.h>
#include <string.h>
int main (){
char greeting[10];
printf("Enter a string:\n");
scanf("%s", greeting);
printf("You entered: \n");
printf("%s", greeting);
return 0;
}
运行代码并检查其输出:
Enter a string:
Hello
You entered:
Hello
Note: 如果数组的大小小于输入字符串的长度,则可能导致垃圾、数据损坏等情况。
String Input with Whitespace
scanf("%s") 读取字符,直到遇到空格(空格、制表符、换行符等)或 EOF。因此,如果您尝试输入一个包含多个单词(以空格分隔)的字符串,那么 C 程序会将第一个空格之前的字符作为字符串的输入。
String Input Using gets() and fgets() Functions
要接受包含空格的字符串输入,我们应该使用 gets() function 。它被称为非格式化控制台输入函数,在 "stdio.h" header file 中定义。
Example: String Input Using gets() Function
请看以下示例:
#include <stdio.h>
#include <string.h>
int main(){
char name[20];
printf("Enter a name:\n");
gets(name);
printf("You entered: \n");
printf("%s", name);
return 0;
}
运行代码并检查其输出:
Enter a name:
Sachin Tendulkar
You entered:
Sachin Tendulkar
在更新版本的 C 中,gets() 已弃用。它可能是一个危险的函数,因为它不执行边界检查,可能会导致缓冲区溢出。
相反,建议使用 fgets() 函数。
fgets(char arr[], size, stream);
fgets() function 可用于接受来自任何输入流的输入,例如 stdin(键盘)或 FILE(文件流)。
Example: String Input Using fgets() Function
以下程序使用 fgets() 并接受用户输入的多单词。
#include <stdio.h>
#include <string.h>
int main(){
char name[20];
printf("Enter a name:\n");
fgets(name, sizeof(name), stdin);
printf("You entered: \n");
printf("%s", name);
return 0;
}
运行代码并检查其输出:
Enter a name:
Virat Kohli
You entered:
Virat Kohli
Example: String Input Using scanf("%[^\n]s")
您还可以使用 scanf("%[^\n]s") 作为替代方案。它读取字符,直到遇到换行符 ("\n")。
#include <stdio.h>
#include <string.h>
int main (){
char name[20];
printf("Enter a name: \n");
scanf("%[^\n]s", name);
printf("You entered \n");
printf("%s", name);
return 0;
}
运行代码并检查其输出:
Enter a name:
Zaheer Khan
You entered
Zaheer Khan
Printing String Using puts() and fputs() Functions
我们一直使用带 %s 说明符的 printf() function 来打印字符串。我们还可以使用 puts() function (在 C11 和 C17 版本中不推荐使用)或 fputs() function 作为替代方案。