头文件string.h中常用函数用法
1.需要包含头文件string.h
2.将数组a清零:memset(a,0,sizeof(a));
3.从数组a复制k个元素到数组b(数组元素为int类型):
memcpy(b,a,sizeof(int)*k);
若把数组a全部复制到数组b中,则为memcpy(b,a,sizeof(a));
4.char *strchr(const char* _Str,char _Val)
功能:查找字符串_Str中首次出现字符_Val的位置
返回值:成功则返回要查找字符第一次出现的位置,失败返回NULL
5.extern unsigned int strlen(char *s);
功能:计算给定字符串的(unsigned int型)长度,不包括’\0’在内
说明:返回s的长度,不包括结束符NULL。
注:s[strlen[s]]=’\0’
有关输入的细节
1.int fgetc(FILE * stream);
fgetc(fin)可以从打开的文件fin中读取一个字符,一般情况下应该在检查它不是EOF后再将其转换成char值。
int getchar(void);
getchar()可以从标准输入读取一个字符,相当于fgetc(stdin)
注:fgetc和getchar将读取下一个字符,如果用scanf(“%d”,%n)读取整数n,要是在输入123后多加了一个空格,用getchar读取的将是这个空格;如果在123后紧跟着换行,则读取到的将是回车符”\n”。
2.char *fgets(char *buf, int bufsize, FILE *stream);
参数:
*buf: 字符型指针,指向用来存储所得数据的地址。
bufsize: 整型数据,指明存储数据的大小。
*stream: 文件结构体指针,将要读取的文件流。
fgets(buf,maxn,fin)将读取完整的一行放在字符数组buf中。应当保证buf能够存放下文件的一行内容。除了在文件结束前没有遇到”\n”这种特殊情况外,buf总是以”\n”结尾(之后是字符串结束符”\0”)。函数成功将返回buf,失败或读到文件结尾返回NULL。因此我们不能直接通过fgets的返回值来判断函数是否是出错而终止的,应该借助feof函数或者ferror函数来判断。
键盘输入fgets(buf,n,stdin)
3.int sprintf( char *buffer, const char *format, [ argument] … );
参数列表
buffer:char型指针,指向将要写入的字符串的缓冲区。
format:格式化字符串。
[argument]…:可选参数,可以是任何类型的数据。
功能是把格式化的数据写入某个字符串中,用法与printf类似
第3章例题与习题代码及分析
例3-1 Tex中的引号(Tex quotes,UVa 272)
本题主要在于字符串的输入及左右引号的判断,注意有空格的字符串不能用scanf(“%s”)读入,引号判断通过设置标志变量即可。
#include <stdio.h>
int main(){
int c,flag=1;
while ((c=getchar())!=EOF){
if (c=='"'){
printf("%s",flag?"``":"''");
flag=!flag;
}
else
printf("%c",c);
}
return 0;
}
例3-2 WERTYU (WERTYU,UVA10082)
此题关键在于输入输出变换,用if语句判断太繁琐,用常量数组会简化不少(无需指明数组大小)
#include<stdio.h>
char s[]="`1234567890-=QWERTYUIOP[]\\ASDFGHJKL;'ZXCVBNM,./'"; //定义一个常量数组 (其中\需用\\转义得到)
int main(){
int i,c;
while ((c=getchar())!=EOF){
for (i=0;s[i]&&s[i]!=c;i++); //查找错位之后的字符在常量表中的位置
if (s[i]) //如果找到,则输出它的前一个字符
putchar(s[i-1]);
else
putchar(c);
}
return 0;
}
注:putchar函数的基本格式为:putchar(c)。
(1)当c为一个被单引号(英文状态下)引起来的字符时,输出该字符(注:该字符也可为转义字符);
(2)当c为一个介于0~127(包括0及127)之间的十进制整型数时,它会被视为对应字符的ASCII代码,输出该ASCII代码对应的字符;
(3)当c为一个事先用char定义好的字符型变量时,输出该变量所指向的字符。
例3-3 回文词 (Palindromes UVa401)
此题回文的判断较为容易,而镜像的判断通过定义一个常量字符数组,按顺序存储A-Z,0-9这些字符的镜像字符(若不存在镜像字符则为空格符)。输出也有两个技巧进行简化,一是通过定义常量字符串数组,二是通过p,m省去多次if判断。
#include <stdio.h>
#include <string.h>
const char rev[]="A 3 HIL JM O 2TUVWXY51SE Z 8 ";
const char* msg[]={
"not a palindrome","a regular palindrome","a mirrored string","a mirrored palindrome"};
bool isPalindrome(char s[]){
int len=strlen(s);
for (int i=0;i<len/2;i++)
if (s[i]!=s[len-i-1])
return false;
return true;
}
bool isMirrored(char s[]){
int len=strlen(s);
for (int i=0;i<len;i++){
char ch=s[i];
if ((ch>='A' && ch<='Z'&& s[len-i-1]!=rev[ch-'A']) ||
(ch>='1' && ch<='9' && s[len-i-1]!=rev[26+ch-'1']))
return false;
}
return true;
}
int main(){
char s[30];
while (scanf("%s",s)==1){
/*if (isPalindrome(s))
if (isMirrored(s))
printf("%s -- is %s.\n\n",s,msg[3]);
else
printf("%s -- is %s.\n\n",s,msg[1]);
else if (isMirrored(s))
printf("%s -- is %s.\n\n",s,msg[2]);
else
printf("%s -- is %s.\n\n",s,msg[0]);
*/
int p=1; int m=1;
if (!isPalindrome(s)) p=0;
if (!isMirrored(s)) m=0;
printf("%s -- is %s.\n\n",s,msg[m*2+p]);
}
}
例3-4 猜数字游戏的提示 (Master-Mind Hints, UVa340)
分析:直接统计可得A,求B:对于每个数组1-9,统计二者出现的次数count1,count2,则min(count1,count2)再减去A即为在两个序列都出现过但位置不对的个数。
#include <stdio.h>
#define MAXN 1005
int main(){
int a[MAXN],b[MAXN];
int n,i,game=0;
while (scanf("%d",&n)==1 && n){
for (i=0;i<n;i++)
scanf("%d",&a[i]);
printf("Game %d:\n",++game);
do{
int strongMatch=0;
for (i=0;i<n;i++){
scanf("%d",&b[i]);
if