C++中的字符串

字符串有三种形式

  • 用双引号括起来的字符串常量,如果"CHINA"、"C++ program"
  • 存放于字符串数组中,以'\0'字符(ASCII吗为0)结尾
  • string对象。string是C++标准模板库里的一个类,专门用于处理字符串(略)。

字符串常量

  • 字符串常量占据内存的字节数等于字符串中字符数目加1,多出来的是结尾字符'\0'
  • 字符串的长度不包含'\0'
  • ""也是合法的字符串常量,称为空串。空串仍然会占据一个字节的存储空间,存放'\0'。
  • 如果字符串常量中包含双引号,则双引号应写为'"'。而''字符在字符串中出现时,须连写两次,变成'\'。例如:
cout << "He said, \"I am a stu\\dent.\"";
// He said, "I am a stu\dent."

用一维char数组存放字符串

  • 包含'\0'字符的一维char数组,就是一个字符串。其中存放的字符串即为'\0'前面的字符所组成。
  • 用char数组存放字符串,数组元素个数应该至少为字符串长度+1
  • char数组的内容,可以在初始化时设定,也可以用C++库函数进行修改,还可以用对数组元素赋值的办法任意改变其中的某个字符。
  • 字符数组同样可以用cout、printf输出,用cin、scanf读入。用cin、scanf将字符串读入字符数组时,会自动在字符数组中字符串的末尾加上'\0'

字符串程序示例

# include <iostream>
# include <cstring> //字符串库函数的声明
using namespace std;
int main()
{
char title[] = "Prison Break"; //title的最后一个元素是'\0'
char hero[100] = "Michael Scofiled";
char prisonName[100];
char response[100];
cout << "What's the name of the prison in " << title << endl;
cin >> prisonName; // input your string
if( strcmp( prisonName, "Fox-River" ) == 0 )
cout << "Yeah! Do you love " << hero << endl;
else{
//function to copy a string
strcpy( response, "It seems you haven't watched it!\n" );
cout << response;
}
title[0] = 't';
title[3] = 0; // equal to title[3] = `\0';
cout << title << endl;
return 0;
}
What's the name of the prison in Prison Break
Fox-River
Yeah! Do you love Michael Scofiled
tri What's the name of the prison in Prison Break
Shark
It seems you haven't watched it!
tri

字符串的输入

  • 用scanf可以将字符串读入字符数组
  • scanf会自动添加结尾的'\0'
  • scanf读入到空格为止
  • 在数组长度不足的情况下,scanf可能导致数组越界
  • cin输入字符串的情况和scanf相同
char line[5];
scanf("%s", line); // Don't use &line
// cin >> line; // 若输入"12345",则数组越界
printf("%s", line);

读入一行到字符数组

  • cin.getline(char buf[], int bufSize);
  • 读入一行(行长度不超过bufSize-1)或bufSize-1个字符到buf,自动添加'\0'。回车换行符不会写入buf,会从输入流中去掉
char line[10];
cin.getline(line, sizeof(line));
// 或 cin.getline(line, 10); 读入最多9个字符到line
cout << line;

读入一行到字符数组

  • gets(char buf[])
  • 读入一行,自动添加'\0'
  • 回车换行符不会写入buf,会从输入流中去掉。如果buf的容量不足,可能导致数组越界!
char s[10];
while( gets(s) ){ // Use Ctrl + C to terminate this program
printf("%s\n", s);
}

字符串库函数

  • 使用字符串库函数需要 #include
  • 字符串库函数都根据'\0'来判断字符串结尾
  • 形参为char []类型,则实参可以是char数组或字符串常量
  • 字符串拷贝strcpy(char dest [], char src []); // copy src to dest
  • 字符串比较大小 int strcmp( char s1 [], char s2 [] ); // if equal then 0 is returned
  • 求字符串长度 int strlen( char s[] );
  • 字符串拼接 strcat(char s1[], char s2[]); // s2拼接到s1后面
  • 字符串转成大写 strupr(char s[]);
  • 字符串转成小写 strlwr( char s[] );

字符串库函数用法示例

#include <iostream>
#include <cstring>
using namespace std;
char* strupr(char* src)
{
while (*src != '\0')
{
if (*src >= 'a' && *src <= 'z')
//在ASCII表里大写字符的值比对应小写字符的值小32.
//*p -= 0x20; // 0x20的十进制就是32
*src -= 32;
src++;
}
return src;
}
void PrintSmall( char s1[], char s2[] ) // 输出词典序小的字符串
{
if( strcmp( s1, s2) <= 0 ) // if s1 is smaller than or equal to s2
cout << s1;
else
cout << s2;
}
int main(){
char s1[30];
char s2[40];
char s3[100];
strcpy(s1, "Hello");
strcpy(s2, s1);
cout << "1) " << s2 << endl; // output: 1) Hello
strcat( s1, " ,world" ); // Now s1 becomes "Hello, world"
cout << "2) " << s1 <<endl; // output: 2) Hello, world
cout << "3) "; PrintSmall("abc", s2); cout << endl; // output: 3) Hello
cout << "4) "; PrintSmall("abc", "aaa"); cout << endl; // output: 4) aaa
int n = strlen( s2 );
cout << "5) " << n << "," << strlen("abc") << endl; // output: 5) 5, 3
strupr(s1);
cout <<"6) " << s1 << endl; // output 6) HELLO, WORLD return 0;
}

strlen的常见糟糕用法

  • strlen函数的执行是需要时间的,且时间和字符串的长度成正比
  • 每次循环,都调用strlen函数,这是效率上的很大浪费
char s[100]="test";
for( int i = 0; i < strlen(s); ++i){
s[i] = s[i]+1;
}

改正版本

  • 应取出s的长度存放在一个变量里面,然后再循环的时候使用该变量
  • 或 使用 s[i]
char s[100]="test";
int len = strlen(s);
for( int i = 0; i < len; ++i){
s[i] = s[i]+1;
}

char s[100]="test";
for( int i = 0; s[i]; ++i){
s[i] = s[i]+1;
}

例题:编写判断字串的函数

编写一个函数:int Strstr(char s1[], char s2[]);

  • 如果s2不是s1的子串,返回-1
  • 如果s2是s1的子串,则返回其在s1中第一次出现的位置
  • 空串是任何串的字串,且出现位置为0
int Strstr(char s1[], char s2[]){
if(s2[0] == 0)
return 0;
for(int i = 0; s1[i]; ++i){ //枚举比较的起点
int k = i, j = 0;
for( ; s2[j]; ++j, ++k ){
if(s1[k] != s2[j])
break;
}
if(s2[j] == 0)
return i;
}
return -1;
}

程序设计与算法(一)C语言程序设计CAP之字符串的更多相关文章

  1. 【算法】C语言趣味程序设计编程百例精解

    C语言趣味程序设计编程百例精解 C/C++语言经典.实用.趣味程序设计编程百例精解(1)  https://wenku.baidu.com/view/b9f683c08bd63186bcebbc3c. ...

  2. 【MOOC课程学习记录】程序设计与算法(一)C语言程序设计

    课程结课了,把做的习题都记录一下,告诉自己多少学了点东西,也能给自己一点鼓励. ps:题目都在cxsjsxmooc.openjudge.cn上能看到,参考答案在差不多结课的时候也会在mooc上放出来. ...

  3. 01 C语言程序设计--01 C语言基础--第1章 C语言概述&第2章 GCC和GDB

    走进嵌入式开发的世界,企业级项目课程让你达到企业嵌入式应用开发要求.名师在线答疑,解决疑难.科学评测体系,系统评估学习.核心项目实........ 30 门课程 241小时12分钟 824 人学习 学 ...

  4. C语言程序设计实习报告

    C语言程序设计实习报告 简介 语言实践心得体会范文在科技高度发展的今天,计算机在人们之中的作用越来越突出.而c语言作为一种计算机的语言,我们学习它,有助于我们更好的了解计算机,与计算机进行交流,因此, ...

  5. 2018年秋季学期《C语言程序设计I》教学过程及学期总结

    一学期下来,问题很多,思考也很多,需要整理.总结,好的经验要形成规律,不好的地方要提示警醒. 教学过程小结: C语言程序设计I-第一周教学 C语言程序设计I-第三周教学 C语言程序设计I-第四周教学 ...

  6. C语言程序设计I—第三周教学

    由于本课程是从教学周的第二周开始上课,所以第二次授课是发生在第三周,为了让PTA.云班课和博客能统一,所以将教学周作为随笔的标题.本周由于处理外聘教师随意退课等事情,总结有些延后了. 第三周教学安排 ...

  7. C语言程序设计50例(经典收藏)

    本篇文章是对C语言程序设计的50个小案例进行了详细的分析介绍,需要的朋友参考下 [程序1]题目:有1.2.3.4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?1.程序分析:可填在百位.十 ...

  8. Python语言程序设计之二--用turtle库画围棋棋盘和正、余弦函数图形

    这篇笔记依然是在做<Python语言程序设计>第5章循环的习题.其中有两类问题需要记录下来. 第一是如何画围棋棋盘.围棋棋盘共有19纵19横.其中,位于(0,0)的星位叫天元,其余8个星位 ...

  9. Python语言程序设计之三--列表List常见操作和错误总结

    最近在学习列表,在这里卡住了很久,主要是课后习题太多,而且难度也不小.像我看的这本<Python语言程序设计>--梁勇著,列表和多维列表两章课后习题就有93道之多.我的天!但是题目出的非常 ...

  10. 《C语言程序设计(第四版)》阅读心得(一)

    本篇开始写我个人觉得谭浩强老师的<C语言程序设计(第四版)>中之前没有认识到,或者忘了的知识.因为本科学过,所以有些简单的东西就没有放进来了,所以可能并不是太全面. 第一章程序设计与语言 ...

随机推荐

  1. angular 2+ 变化检测系列二(检测策略)

    我们将创建一个简单的MovieApp来显示有关一部电影的信息.这个应用程序将只包含两个组件:显示有关电影的信息的MovieComponent和包含执行某些操作按钮的电影引用的AppComponent. ...

  2. 设计模式学习之享元模式(Flyweight,结构型模式)(20)

    转:http://terrylee.cnblogs.com/archive/2006/03/29/361767.html 摘要:面向对象的思想很好地解决了抽象性的问题,一般也不会出现性能上的问题.但是 ...

  3. C++运算符重载——输入/输出运算符

    为了与IO标准库一致,重载输入输出运算符函数的第一个行参应该是流的引用,第二个行参是对象的引用. 如果重载为类的成员函数,第一个行参应该是对象的引用,第二个行参是流的引用. 使用方式是 ClassOb ...

  4. windows应用程序框架及实例

    应用程序框架:同一类型应用程序的结构大致相同,并有很多相同的源代码,因此可以通过一个应用程序框架AFX(Application FrameWorks)编写同一类型应用程序的通用源代码. 主要向导: D ...

  5. 2017-10-22—发光二极管

    LED与 LD的差别在工作原理上的差别:LED是利用注入有源区的载流子自发辐射复合发光,而LD是受激辐射复合发光.在结构上的差别:LD有光学谐振腔,使产生的光子在腔内振荡放大,LED没有谐振腔.性能上 ...

  6. Node.js_Buffer 缓冲区

    Buffer 缓冲区 虽然 JavaScript 支持未操作,但是并没有 二进制数据 的原生 node 引入了 Buffer 类,用于操作二进制数据 是 V8 引擎的扩展,实际上是对内存的直接分配 每 ...

  7. linux中安装和配置 jdk

    01.去官网下载指定的jdk 02.使用xftp把下载好的文件 传递到 linux指定文件夹中03.进入指定的文件夹输入tar -zxvf 文件名称04.发现文件 05.进入文件cd jdk1.8.0 ...

  8. JS节流和防抖

    事件的触发权很多时候都属于用户,有些情况下会产生问题: 向后台发送数据,用户频繁触发,对服务器造成压力 一些浏览器事件:window.onresize.window.mousemove等,触发的频率非 ...

  9. java验证码生成

    第一种方式:纯代码 先写jsp: 在编写CaptServlet: package cn.itcast.web.controller; import java.awt.Color; import jav ...

  10. python在读取文件时出现 'gbk' codec can't decode byte 0x89 in position 68: illegal multibyte sequence

    python在读取文件时出现“UnicodeDecodeError:'gbk' codec can't decode byte 0x89 in position 68: illegal multiby ...