Skip to content

C 风格字符串

C 风格的字符串起源于 C 语言,并在 C++ 中继续得到支持。字符串实际上是使用 null 字符 \0 终止的一维字符数组。因此,一个以 null 结尾的字符串,包含了组成字符串的字符。

下面的声明和初始化创建了一个 Oldmoon 字符串。
由于在数组的末尾存储了空字符,所以字符数组的大小比单词 Oldmoon 的字符数多一个。

c
char s1[8] = {'O','l','d','m','o','o','n','\0'};

依据数组初始化规则,您可以把上面的语句写成以下语句:

c
char s1[] = "Oldmoon";

输入输出方式

在 C 语言中,有函数可以让用户从键盘上输入字符串,它就是:

注意

  • scanf():通过格式控制符%s 输入字符串。除了字符串,scanf() 还能输入其他类型的数据。

scanf() 读取字符串时以空格为分隔,遇到空格就认为当前字符串结束了,所以无法读取含有空格的字符串。

输入输出方式 示例代码
cpp
#include<bits/stdc++.h>
using namespace std;
int main()
{
    char s1[30];
    //请输入一个字符串
    scanf("%s",s1);
    printf("s1:%s",s1);
    return 0;
}

运行结果:

```c
输入:
welcome oldmoon↙(表示输入结束)
输出:
s1: welcome

分析

使用 scanf 输入,遇到空格就认为当前字符串结束了,所以输入 welcome oldmoon,输出是 welcome。

  • 为了解决上面得问题,我们可以这样修改:

    scanf("%[^\n]",s) 能解决这个问题,一直读取,直到遇到\n 结束,空格当成普通字符读入。

输入输出方式 示例代码
cpp
#include<bits/stdc++.h>
using namespace std;
int main()
{
    char s1[30];
    //请输入一个字符串
    scanf("%[^\\n]s",s1);
    printf("s1:%s",s1);
    return 0;
}

运行结果:

c
输入:
welcome oldmoon↙(表示输入结束)
输出:
s1: welcome oldmoon

分析

从输出上可以看出,空格当作普通字符读取了,直到遇到换行,字符串才结束

也可通过 C++中的cin进行输入

注意

对于一次 cin 调用,在没有读到非空白字符前它会将遇到的所有空白字符丢弃(不会停止读取),在读到非空白字符之后遇到空白字符 cin 将停止读取。

空白字符:所谓空白符其实就是空格、制表符、换行符的统称

C 风格字符串 示例代码
cpp
#include<bits/stdc++.h>
using namespace std;
int main()
{
    char s4[30];
	//输入一个字符串
	cin >> s4 ;
    cout << s4 << endl;
    return 0;
}

运行结果:

c
输入一个字符串:welcome oldmmon↙(表示输入结束)
welcome

分析

跟 scanf 比较相像,遇到空格即结束,所以输入的 welcome oldmmon,最终输出的 welcome。
一定要多去尝试哦~

示例

C 风格字符串 示例代码
cpp
#include<bits/stdc++.h>
using namespace std;
int main()
{
    char s1[] = "Oldmoon";
	cout << "欢迎来到:" << s1 << endl;
    return 0;
}

运行结果:

c
欢迎来到:Oldmoon

C 风格字符串 相关函数

常用函数

加上头文件 string.h 或 cstring

  • strlen
  • strcmp
  • strcat
  • strcpy
  • memset

strlen

strlen(s1)

返回字符串 s1 的长度,长度不包含'\0'。

strlen 示例代码
cpp
#include<bits/stdc++.h>
using namespace std;
int main()
{
    char s1[] = "Oldmoon";
	cout << "字符串的长度是:" << strlen(s1) << endl;
    return 0;
}

运行结果:

c
字符串的长度是:7

使用的是万能头,所以不需要加上头文件 string.h :::

strcmp

strcmp(s1,s2)

比较字符串 s1 和 s2。
若 s1 = s2,则返回零;若 s1 < s2,则返回负数;若 s1 > s2,则返回正数。
两个字符串自左向右逐个字符相比(按 ASCII 值大小相比较),直到出现不同的字符或遇'\0'为止。

strcmp 示例代码
cpp
#include<bits/stdc++.h>
using namespace std;
int main()
{
    char s1[] = "Oldmoon";
	char s2[] = "Oldmoon";
	cout << "s1 和 s2 进行比较的结果: " << strcmp(s1,s2) << endl;
    return 0;
}

运行结果:

c
s1 和 s2 进行比较的结果: -1(数值不固定,但是是负数)

答案是几不重要,重要的是负数,说明 s1 小于 s2
两个字符串自左向右逐个字符相比,O 跟 o 的 ASCII 值进行比较,O 小于 o,所以直接返回负数结果。

建议

尝试两个相同的字符串运行看看效果呦

strcat

strcat(s1,s2)

把 s2 所指向的字符串(包括"\0")复制到 s1 所指向的字符串后面(删除 s2 原来末尾的“\0”)。

要保证 s1 足够长,以容纳被复制进来的 s2。s2 中原有的字符不变。

strcat 示例代码
cpp
#include<bits/stdc++.h>
using namespace std;
int main()
{
    char s1[20] = "welcome ";
	char s2[20] = "Oldmoon";
    strcat(s1,s2);
	cout << "strcat(s1,s2): " << s1 << endl;
    return 0;
}

运行结果:

c
strcat(s1,s2): welcome Oldmoon

s1 字符串的空间一定要要确保能放得下 s1 和 s2 :::

strcpy

strcpy(s1,s2)

把从 s2 地址开始且含有 NULL 结束符的字符串复制到以 s1 开始的地址空间

要保证 s1 必须有足够的空间来容纳 s2 的字符串。

strcpy 示例代码
cpp
#include<bits/stdc++.h>
using namespace std;
int main()
{
    char s1[20] = "hello ";
	char s2[20] = "Oldmoon";
	strcpy(s1,s2);
	cout << "strcpy(s1,s2): " << s1  << endl;
    return 0;
}

运行结果:

c
strcpy(s1,s2): Oldmoon

s1 字符串的空间一定要要确保能放得下 s2。 :::

memset

memset(void *str, int c, size_t n)

复制字符 c(一个无符号字符)到参数 str 所指向的字符串的前 n 个字符

str : 指向要填充的内存块。
c : 要被设置的值。该值以 int 形式传递,但是函数在填充内存块时是使用该值的无符号字符形式。
n : 要被设置为该值的字符数。

memset 示例代码
cpp
#include<bits/stdc++.h>
using namespace std;
int main()
{
    char str[50] = "welcome,oldmoon" ;
	memset(str,&apos;$&apos;,7);
	cout << str << endl;
    return 0;
}

运行结果:

c
$$$$$$$,oldmoon

建议

memset 也慢慢的变成大家进行初始化的一种写法。
例如:

cpp
int arr[50];
memset(arr,0,sizeof(arr));

是一种将数组 arr 所有数据初始化为 0 的方式,写法简单。

拓展内容

以下为拓展内容

转义字符

转移字符意义
\a警告声
\b退回
\f换页
\n换行
\r回车
\t水平 Tab
\v垂直 Tab
\\右斜线
'单引号
"双引号
?问号
\0Null
转义字符 示例代码
cpp
#include<bits/stdc++.h>
using namespace std;
int main()
{
    printf("You\\nare\\nlearning\\n\\&apos;C++\\&apos; language\\n\\t\\"Do you know C++language\\"");
    return 0;
}