【C语言】Coursera课程《计算机程式设计》台湾大学刘邦锋——Week6 String课堂笔记
本笔记记录自 Coursera课程 《计算机程式设计》 台湾大学 刘邦锋老师
Week6 String
6-1 Character and ASCII
字符变量的声明
char c;
C语言使用一个位元组来储存一个字符,所以一个字符能存一个-128到127之间的整数。
例子:(char-size.c)一个char所占的位元组数
#include <stdio.h>
int main(void)
{
char c;
printf("%d\n", sizeof(c));
return 0;
}
输出
1
字符的输出
printf("%c", c);
- 字符最大的用处就是以ASCII码的形式将文字讯息显示出来。
- ASCII码(American Standard Code for Information Interchange),就是将0到127的整数对应到我们常用的英文大小写字母,0到9的数字,以及标点符号等。
例子:(ascii.c)印出部分ASCII码
#include <stdio.h>
int main(void)
{
char c;
int i, j;
printf("0123456789abcdef\n");
for (i = 2; i <= 7; i++){
for (j = 0; j <= 15; j++){
c = i * 16 + j;
printf("%c", c);
}
printf("\n");
}
return 0;
}
输出
0123456789abcdef
!"#$%&'()*+,-./
0123456789:;<=>?
@ABCDEFGHIJKLMNO
PQRSTUVWXYZ[\]^_
'abcdefghijklmno
pqrstuvwxyz{|}~-
- 这个程序印出由32到127的ASCII码。对应到的16进位数字是20到7F,我们选这个范围是因为32之前的都是特殊字符。
- 输出是16个字符一行,而且在第一行加上0到f的16进位。
6-2 Character Constant and Integer
- 字符常数将字符串的ASCII值和它所代表的符号连接起来。
- C中字符常数是用一对单引号将一个符号括起来,代表它的ASCII值。
例子:(char-assignment.c)将字符常数指定给字符串变量
#include <stdio.h>
int main(void)
{
char c;
c = 'm';
printf("%c", c);
c = 'a';
printf("%c", c);
c = 'i';
printf("%c", c);
c = 'n';
printf("%c", c);
c = '(';
printf("%c", c);
c = ')';
printf("%c", c);
c = '\n';
printf("%c", c);
c = '{';
printf("%c", c);
c = '\n';
printf("%c", c);
c = '}';
printf("%c", c);
return 0;
}
输出结果
main()
{
}
6-3 Character Input and C-type Functions
字符的输入
scanf("%c", &c);
例子:(char-io.c)输入一个字符分别用字符或整数输出
#include <stdio.h>
int main(void)
{
char c;
scanf("%c", c);
printf("%c\n", c);
printf("%d\n", c);
return 0;
}
输入
a
输出
a
97
借由scanf的返回值判定是否还有数据
while (scanf("%c", &c) != EOF){
...
process character c;
}
使用字符分类函数
#include <ctype.h>
...
char c;
...
if (isxxxxx(c))
- 系统的<ctype.h>中定义了一些好用的字符处理函数。
- 字符分类函数
- 字符转换函数
- 字符分类函数决定传进来字符是否属于某一类字符。
- isalpha(c)会判断c是否为英文字母
字符串分类函数表
函数名称 | 分类 |
---|---|
isalnum | 英文字母或数字 |
isalpha | 英文字母 |
islower | 小写英文字母 |
isupper | 大写英文字母 |
isdigit | 数字 |
isxdigit | 16进位数字 |
isprint | 可显示字符(包含空白) |
isgraph | 可显示字符串(不包含空白) |
isspace | 空白 |
ispunct | 标点符号 |
iscntrl | 控制字符 |
6-4 Character Input EOF
在命令行形式下可以打CTRL+D来结束程序。
6-5 ASCII Table in Decimal Format
例子:(ascii-dec.c)用十进位印ASCII表
#include <stdio.h>
int main(void)
{
int c;
printf(" 0123456789\n");
for (c = 30; c <= 127; c++){
if (c % 10 == 0)
printf("%2d ", c / 10);
if (isprint(c))
printf("%c", c);
else
printf(" ");
if (c % 10 == 9)
printf("\n");
}
return 0;
}
输出结果
0123456789
3 !"#$%&'
4 ()*+,-./01
5 23456789:;
6 <=>?@ABCDE
7 FGHIJKLMNO
8 PQRSTUVWXY
9 Z[\]^_'abc
10 defghijklm
11 nopqrstuvw
12 xyz{|}~
- 想输出的范围是32到127可印出的部分。
- 用isprint()检查是否列印,或是用空白代替。
- 每一行的开始会印出十进位的前两位。为了对齐,这前两位指定用两位数字印出。方法是在%及d中放一个2。
6-6 Toupper and Tolower Functions
字符转换函数
函数名称 | 动作 |
---|---|
tolower | 转成小写英文字母 |
touppper | 转成大写英文字母 |
6-7 String Declaration
字符串的声明
char s[80];
- 字符是专门用来处理文字资料的。而文字资料一般都是成批出现的。单独使用字符来处理成批的文字资料很麻烦,所以我们可以使用字符串来处理。
- C语言以字符数组代表字符串。
- 字符串的声明就必须制定足够的数组长度,也就是字符串的长度,来储存字符串中的字符。
例子:(string-size.c)字符串所占的记忆体位元组数
#include <stdio.h>
int main(void)
{
char s[80];
printf("%D\n", sizeof(s));
return 0;
}
输出
80
例子:(string-init.c)使用数组的方式初始化一个字符串
#include <stdio.h>
int main(void)
{
char s[80] = {'m', 'a', 'i', 'n', '(', ')', '\n', '{', '\n', '}', '\n'};
int i;
for (i = 0; i < 11; i++)
printf("%c", s[i]);
return 0;
}
- C语言字符串处理的管理是字符串范围到'\0'这个特殊字符为止。这个特殊字符位元组中所有的位元皆为0。
用printf印出字符串
printf("%S", string);
6-8 Empty String
- 字符串常数和字符常数很类似,只不过字符串常数是用双引号,而字串常数是用单引号。
- printf输出一个整数的参数"%d"就是字符串常数。
例子:(string-init-double-quote.c)使用字符串常数的方式初始化
#include <stdio.h>
int main(void)
{
char s[80] = "main()\n{\n}\n";
printf("%s", s);
return 0;
}
- 空字符串写成“”
- 空字符串的第一个字符就是'\0',所以它只占1个位元组。
6-9 String Input
例子:(string-io.c)字符串的输入
#include <stdio.h>
int main(void)
{
int i;
char string[10];
while (scanf("%s", string) != EOF){
printf("%s\n", string);
for (i = 0; i < 10 && string[i] != '\0'; i++)
printf("%c ", string[i]);
printf("\n");
}
return 0;
}
- scanf读字符串遇到空格就会断开,而不是读整行。
6-10 Character Pointer
指向一个字符数组的字符指针也能当字符串
char string[80];
char *ptr = string;
例子:(char-pointer.c)指向一个字符数组的字符指针
#include <stdio.h>
#include <string.h>
int main(void)
{
char string[80];
char *ptr = string;
int i;
scanf("%s", ptr);
printf("%s\n", ptr);
for (i = 0; i < strlen(ptr); i++)
printf("%c ", ptr[i]);
return 0;
}
输入
programming
输出
programming
p r o g r a m m i n g
字符指针类别的字符串也可以有初始值
char *string = "programming";
6-11 Strien Usage
- <string.h>标头档中定义了许多好用的函数,用之前记得要引入。
函数strlen
int strlen(char *string);
- strlen(string length)计算一个字符串的长度
- strlen接受一个字符指针参数,这个指针指向要算长度的字串,算出字符串长度并返回。
6-12 Strcpy Strcat
函数strcpy与函数strcat
char *strcpy(char *destination, char *source);
char *strcat(char *destination, char *source);
- strcpy(string copy)将source参数字符串复制到destination参数字符串,并返回destination的位址。
- source字符串的结束字符'\0'也会被复制到destination字串。
- strcat与strcpy类似,但strcat会将第二个字符串参数复制并接到第一个字符串参数的后面。
6-13 Strncpy Strncat
缓冲区覆盖
- 在使用strcpy及strcat时我们有可能尝试将太长的字符串复制进目的字符串,以致超过目的字符串的长度。
- 如果目的字符串的后面还有重要的数据,这些数据就会被破坏。这个现象称为缓冲区覆盖(buffer overrun)。
函数strncpy与函数strncat
char *strncpy(char *dest, char *source, int i);
char *strncat(char *dest, char *source, int i);
- strncpy可由第三个参数i控制“至多”要覆盖几个字符,避免缓冲区覆盖。
- strncpy不会帮你补结束字符'\0',而是要自己加。
例子:(buffer-no-overrun.c)strncpy避免超过长度
#include <stdio.h>
#include <string.h>
int main(void)
{
char destination[16];
char source[80];
printf("destination at %p\n", destination);
printf("%s", source);
scanf("%s", source);
printf("source = %s\n", source);
strncpy(destination, source, 15);
destination[15] = '\0';
printf("source = %s\n", source);
printf("destination = %s\n", destination);
reutrn 0;
}
6-14 Strcmp and String Sorting
函数strcmp与函数strncmp
int strcmp(char *string1, *string2);
int strncmp(char *string1, *string2, int n);
- strcmp比较两个字符串string1及string2的大小。strncmp只比较到n个字符。
- 如果第一个字符串string1比较小则返回一个负数。
- 如果第一个字符串string1比较大则返回一个正数。
- 如果一样大则返回0。
- 两个字符串的大小比法是由第一个字符开始按ASCII码的大小开始比,如果相同则比第二个字符,直到比出大小或是最后一个字符结束为止。
字符串排序
- 十二生肖的字符串放在一个二维字符串数组里,第一维代表十二生肖,第二维代表字符串。
- 使用两层for循环操作泡沫排序法。
- 第一层循环决定两两交换的范围。
- 第二层循环实际作两两交换。
- 使用strcmp比较两个生肖字符串。
例子:(string-sort.c)将字符串排序
#include <stdio.h>
#include <string.h>
int main(void)
{
char zodiac[12][40];
int i, j;
char temp[40];
for (i = 0; i < 12; i++)
scanf("%s", zodiac[i]);
for (i = 10; i >= 1; i--)
for (j = 0; j <= i; j++)
if (strcmp(zodiac[j], zodiac[j + 1]) > 0){
strcpy(temp, zodiac[j]);
strcpy(zodiac[j], zodiac[j + 1]);
strcpy(zodiac[j + 1], temp);
}
for (i = 0; i < 12; i++)
printf("%s\n", zodiac[i]);
return 0;
}
输入
rat
ox
tiger
hare
dragon
snake
horse
sheep
monkey
rooster
dog
pig
输出
dog
dragon
hare
horse
monkey
ox
pig
rat
rooster
sheep
snake
tiger
例子:(string-pointer-sort.c)使用指针数组将字符串排序
#include <stdio.h>
#include <string.h>
int main(void)
{
char zodiac[12][40];
char *zptr[12];
int i;
int j;
char *temp;
for (i = 0; i < 12; i++){
scanf("%s", zodiac[i]);
zptr[i] = zodiac[i];
}
for (i = 10; i >= 1; i--)
for (j = 0; j<= i; j++)
if (strcmp(zptr[j], zptr[j + 1]) > 0){
temp = zptr[j];
zptr[j] = zptr[j + 1];
zptr[j + 1] = temp;
}
for (i = 0; i < 12; i++)
printf("%s\n", zptr[i]);
return 0;
}
6-15 Strtok
函数strtok
char *strtok(char *string, char *delimeters);
- strtok(string to token)把第一个字符串参数string切成一段一段的token。
- token是第一个字符串中被第二个字符串参数delimeters中的任何字符所隔开的部分。
例子:(strtok.c)使用strtok将字串切成token
#include <stdio.h>
#include <string.h>
int main(void)
{
char delimeters[] = "/";
char pathname[40];
char file[40][40];
int file_count = 0;
char *start = pathname;
int copy_length;
int i;
scanf("%s", pathname);
start = strtok(start, delimeters);
while (start != NULL){
strcpy(file[file_count], start);
file_count++;
start = strtok(NULL, delimeters);
}
for (i = 0; i < file_count; i++)
printf("%s\n", file[i]);
printf("After strtok pathname becomes %s\n", pathname);
return 0;
}
输入
/usr/local/bin/emacs
输出
usr
local
bin
emacs
After strtok pathname becomes /usr
测验代码
自己写的
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main(void)
{
char sentence[100][40];
int i = 0;
int j;
int n;
int start_num = 0;
int end_num = 0;
int k;
int p = 0;
char output[40];
//输入字符串
while (scanf("%s", sentence[i]) != EOF)
i++;
//分割词组,并打印
for (j = 0; j < i; j++){
n = strlen(sentence[j])-1;
if (isalpha(sentence[j][n]))
end_num++;
else{
end_num = j;
for (k = start_num; k <= end_num; k++)
if ((strcmp(sentence[k], "of") != 0) && (strcmp(sentence[k], "and") != 0) && (strcmp(sentence[k], "the") != 0) && (strcmp(sentence[k], "at") != 0)){
output[p]=toupper(sentence[k][0]);
p++;
}
printf("%s ", output);
strncpy(output, "",p);
p = 0;
start_num = j + 1;
end_num = j + 1;
}
}
return 0;
}
老师写的
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int main ()
{
char str[128];
int flag = 0;
while ( scanf ( "%s", str ) != EOF ) {
if ( flag ) {
printf ( " " );
flag = 0;
}
if ( strchr ( str, '.' ) )
flag = 1;
if ( !strcmp ( str, "and" ) || !strcmp ( str, "at" ) ||
!strcmp ( str, "of" ) || !strcmp ( str, "the" ) )
continue;
printf ( "%c", toupper ( str[0] ) );
}
return 0;
}
以及安利一个C的在线编译器,比老师推荐的ideone速度快些,也更清爽些。
【C语言】Coursera课程《计算机程式设计》台湾大学刘邦锋——Week6 String课堂笔记的更多相关文章
- Coursera课程《Machine Learning》吴恩达课堂笔记
强烈安利吴恩达老师的<Machine Learning>课程,讲得非常好懂,基本上算是无基础就可以学习的课程. 课程地址 强烈建议在线学习,而不是把视频下载下来看.视频中间可能会有一些问题 ...
- 【Python学习笔记】Coursera课程《Python Data Structures》 密歇根大学 Charles Severance——Week6 Tuple课堂笔记
Coursera课程<Python Data Structures> 密歇根大学 Charles Severance Week6 Tuple 10 Tuples 10.1 Tuples A ...
- 《计算机程式设计》Week5 课堂笔记
本笔记记录自 Coursera课程 <计算机程式设计> 台湾大学 刘邦锋老师 Week5 Pointer 5-1 Pointer Definition and Declaration 指针 ...
- 《计算机程式设计》Week3 课堂笔记
本笔记记录自 Coursera课程 <计算机程式设计> 台湾大学 刘邦锋老师 Week3 Array 3-1 Array Usage 例子:使用数组一次申明10个整数变量 int a[10 ...
- 《计算机程式设计》Week4 课堂笔记
本笔记记录自 Coursera课程 <计算机程式设计> 台湾大学 刘邦锋老师 Week4 Functions 4-1 System Function 函数主要分为两大类系统定义函数与使用者 ...
- 《计算机程式设计》Week2 课堂笔记
本笔记记录自 Coursera课程 <计算机程式设计> 台湾大学 刘邦锋老师 Week2 Control Structure 2-1 If-then-else if then 判断 if ...
- 【DeepLearning学习笔记】Coursera课程《Neural Networks and Deep Learning》——Week2 Neural Networks Basics课堂笔记
Coursera课程<Neural Networks and Deep Learning> deeplearning.ai Week2 Neural Networks Basics 2.1 ...
- C语言程序设计课程总结
第一次教授C语言程序设计课程,相比计算机组成原理.arm体系结构等偏向硬件的课程,C的教学方式要灵活一些.计算机组成原理课程偏向理论,哈尔滨工业大学的计算机组成原理是国家精品课,增加了mooc+spo ...
- 第一次使用博客及Coursera课程体验
前言: 第一天的学习目标有三个 开设博客园账户 开设Github账号 进行第一次coursera课程学习:Internet History, Technology, and Security (网址 ...
随机推荐
- Delphi 的绘图功能[8] - TextOut、TextWidth、TextHeight
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, For ...
- 第24天:js-函数变量声明提升
一.函数声明1.自定义函数function fun1(){ alert("我是自定义函数");}fun2();//函数不调用,自己不执行2.直接量声明var fun2=functi ...
- canvas画布上定位点击位置
两种方法: 1. cvs.onclick = function (e) { if (e.offsetX || e.layerX) { var x = e.offsetX == undefined ? ...
- nargchk函数 matlab【转】
功能说明 验证输入参数的个数 函数语法 msgstring = nargchk(minargs, maxargs, numargs)msgstring = nargchk(minargs, max ...
- 限制玻尔兹曼机(Restricted Boltzmann Machine)RBM
假设有一个二部图,每一层的节点之间没有连接,一层是可视层,即输入数据是(v),一层是隐藏层(h),如果假设所有的节点都是随机二值变量节点(只能取0或者1值)同时假设全概率分布满足Boltzmann 分 ...
- 【bzoj4842】[Neerc2016]Delight for a Cat 线性规划与网络流
题目描述 $n$ 个连续的位置,每个位置可以填入 S 和 E ,第 $i$ 个位置填入 S 可以获得 $s_i$ 的收益,填入 E 可以获得 $e_i$ 的收益.要求每连续的 $k$ 个位置必须包含至 ...
- 【题解】Atcoder AGC#03 E-Sequential operations on Sequence
仙题膜拜系列...首先我们可以发现:如果在截取了一段大的区间之后再截取一段小的区间,显然是没有什么用的.所以我们可以将操作序列变成单调递增的序列. 然后怎么考虑呢?启示:不一定要考虑每一个数字出现的次 ...
- 【以前的空间】BIT的两个小小运用
剩下一点点时间,就来说说最近才会的关于bit的两个妙用. 求一组数的逆序对 求最长不下降序列 其实两个东西思想差不多,就已第一个为例讲讲. 就是所有数排一遍后,再按照原序列顺序(从后往前),做如下操作 ...
- HDU5115:Dire Wolf——题解+翻译
http://acm.hdu.edu.cn/showproblem.php?pid=5115 题目大意:给n匹狼,每一次攻击可以秒杀一匹狼,但同时会受到这匹狼的a攻击和它相邻两只狼的b攻击. 给定a, ...
- bzoj2144: 跳跳棋(二分/倍增)
思维好题! 可以发现如果中间的点要跳到两边有两种情况,两边的点要跳到中间最多只有一种情况. 我们用一个节点表示一种状态,那么两边跳到中间的状态就是当前点的父亲,中间的点跳到两边的状态就是这个点的两个儿 ...