-
字符串的表示
我粗略总结一下,在C,C++,Java,Python中字符串的表示方式。反正我在学习之初是晕头转向的,感觉乱七八糟。
C语言
在C语言中,字符串是以字符数组的形式表示的,以null字符('\0')结尾。
C++语言
一方面,C++继承了C语言的字符串表示方式。另一方面,C++还引入了标准库中的`std::string`类,它提供了更多的字符串操作功能。使用字符数组:
char str[] = "Hello, World!";
或者使用`std::string`:
#include <string>
std::string str = "Hello, World!";
Java语言
在Java中,字符串是通过`String`类来表示的,它是一个引用类型。Java字符串是不可变的,这意味着一旦创建就不能修改。例如:
Python语言
在Python中,字符串是一个内置的基本数据类型,即'str'类型。它可以用单引号或双引号括起来。Python的字符串是可变的,可以通过不同的方法进行操作。
此外,Python还支持原始字符串(raw strings),它们以字母`r`或`R`开头,不会处理反斜杠`\`为转义字符。例如:
raw_str = r"C:\Users\Username"
这就是这四种编程语言中字符串的基本表示方法。每种语言都有自己的字符串处理函数和方法,可以用来执行各种操作,如拼接、切片、查找等。
-
字符串的读取
这里我主要说一下C/C++的字符串读取方式。
scanf函数
scanf
是一个通用的输入函数,可以用于读取字符串。使用 %s
格式说明符来读取字符串,但要注意它会以空白字符(空格、制表符、换行符等)为分隔符,因此无法读取带空格的字符串。也可以使用%c格式说明符来读取单个字符。
gets函数和fgets函数
这两个函数是差不多的,只是gets函数无法指定要读取的字符串的最大长度,这容易导致缓冲区溢出。而fets函数允许指定要读取的最大字符数。
fgets
函数在C语言中的标准声明为:
char *fgets(char *str, int n, FILE *stream);
其中,str
是指向用于存储读取字符串的字符数组的指针,n
是要读取的最大字符数(包括终止符和换行符),而 stream
是输入流,通常是文件指针,用于指定要从哪个流中读取数据。
使用fgets函数必须要三个参数全部提供。第三个参数,一般为stdin(只要你是从键盘/控制台输入,也即标准输入流)。
#include <stdio.h>
int main() {
char str[100];
char str2[100];
char c1;
fgets(str,34,stdin);
printf("%s\n", str);
gets(str2);
puts(str2);
scanf("%c",&c1);
printf("%c",c1);
return 0;
}
运行结果
hello world!
hello world!
hello world!
hello world!
a
a
getchar函数
getchar函数一般不用来真正意义上读取字符串,因为它的参数是void,也即不接受参数。
getchar函数的声明为:
int getchar(void);
我们一般用getchar来清除缓冲区
就比如
#include <stdio.h>
int main() {
char c1,c2,c3;
scanf("%c",&c1);
getchar();
scanf("%c",&c2);
getchar();
scanf("%c",&c3);
printf("%c%c%c",c1,c2,c3);
return 0;
}
运行结果
a b c
abc
假如不清冲缓冲区,就会出现下面的情况:
#include <stdio.h>
int main() {
char c1,c2,c3;
scanf("%c",&c1);
//getchar();
scanf("%c",&c2);
//getchar();
scanf("%c",&c3);
printf("%c%c%c\n",c1,c2,c3);
printf("--------------------\n");
char c4,c5;
scanf("%c%c",&c4,&c5);
printf("%c%c",c4,c5);
return 0;
}
下面是运行结果
a b c
a b
--------------------
c
cin读取
cin的话就简单太多了,读取字符串或者字符,都一样的,直接cin >>。但是,cin是不能够读取带空格的字符串的。
#include<bits/stdc++.h>
using namespace std;
int main(){
char c1,c2;
char arr1[20];
cin >> arr1;
cout << arr1;
// cin >> c1 >> arr1 >> c2;
// cout << arr1;
// cout << c2;
return 0;
}
运行结果:
hello world!
hello
如果想要读取带空格的字符串,需要用C++中的getline函数搭配string类。这里不展开来说了。
-
字符串的长度
字符串的结束标志。
1,C语言
在C语言中,字符串是用 null 字符('\0')作为结束符的。这个 null 字符是一个二进制零(所有位都是零)的字符,ASCII码为0。在字符串中,它表示字符串的结束。这也被称为字符串的"null终止符"。当使用字符串函数(比如strlen
、strcpy
等)时,它们会在碰到 null 终止符时停止对字符串的处理。
char myString[] = "Hello, World!";
在这个字符串的内部,实际上是包含了字符序列 "Hello, World!" 以及一个 null 终止符。所以在内存中,这个字符串实际上是由字符 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!', '\0' 组成的。
2,C++
在C++中,字符串是通过C++标准库中的 std::string
类型来表示的,而不是像C语言一样使用字符数组。在std::string
类型中,字符串的结束并不依赖于特殊的字符,而是通过记录字符串的长度来实现。
在C++的 std::string
类型中,字符串的长度可以通过 length()
或者 size()
成员函数来获取。字符串的结束并不需要类似C语言的 null 终止符。
#include <iostream>
#include <string>
int main() {
std::string myString = "Hello, World!"; // 字符串
std::cout << "Length of the string: " << myString.length() << std::endl;
std::cout << "String: " << myString << std::endl;
return 0;
}
在C++中,std::string
类型提供了一系列成员函数用于字符串的操作,而不需要像C语言那样依赖于 null 终止符。
关于sizeof与strlen
在C语言中,strlen
函数用于计算一个字符串的长度,即字符串中字符的个数,不包括字符串末尾的 null 终止符。
#include<stdio.h>
#include<string.h>
int main() {
char c1;
char arr1[] = {'h','e','l','l','o'};
char arr2[5];
char arr3[] = "hello";
scanf("%s",arr2);
printf("%d\n",sizeof(arr1));
printf("%d\n",strlen(arr1));
printf("%d\n",sizeof(arr2));
printf("%d\n",strlen(arr2));
printf("%d\n",sizeof(arr3));
printf("%d\n",strlen(arr3));
return 0;
}
上述代码运行结果是
hello(hello是我输入的)
5
5
5
5
6
5
从运行结果我们可以看出,只有直接初始化为字符串,sizeof才会计算'\0',而如果你单个字符单个字符的输入,或者从控制台输入,sizeof函数都是不计算'\0'的。