01.scanf
1)scanf将回车空格都当作字符串结束的标志
2)以回车键作为输入完成的标识,但是回车键本身不会作为字符串的一部分
3)存在安全问题,加入用户在键盘输入的内容超过scanf参数中的数组长度,就会内存溢出,发生奔溃,这也就是微软在使用scanf函数时需要加上顶部#define
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {
char buf[100] = { 0 };
printf("请输入字符串buf:");
scanf("%s",buf);
printf("buf=%s\n", buf);
char temp[100] = { 0 };
printf("请输入字符串temp:");
scanf("%s", temp);
printf("buf=%s\n", temp);
//scanf不做越界检查,所以是不安全的,
//如果输入的数量超过了数组长度,就会发生异常
char str[10] = { 0 };
printf("请输入字符串str:");
scanf("%s", str);
printf("buf=%s\n", str);
system("pause");
}
控制台:
请输入字符串buf:hello
buf=hello
请输入字符串temp:world
buf=world
请输入字符串str:haha
buf=haha
请按任意键继续. . .
加入我这样输入,一次性输入三个单词,以空格隔开,看打印的情况,
请输入字符串buf:hello world haha
buf=hello
请输入字符串temp:buf=world
请输入字符串str:buf=haha
请按任意键继续. . .
我们可以分析一下scanf的工作原理,在键盘上输入hello world haha
回车之后,会将hello world haha\n放入缓冲区(内存),这时运行
到scanf函数的时候,会去缓冲区中检查,看有没有输入的内容,如
果没有则等待输入,如果有,则取出一个,以空格为标识,取出了
第一个hello,然后第二个scanf同样道理,取出第二个单词world,第
三个取出最后一个
sscanf(按照指定的格式提取内容)
scanf可以理解为按照指定格式(以空格分隔的格式),从标准输入中提取内容,那么sscanf就是按照指定格式(不再局限于空格分隔),从指定的内容中,一般是字符串中,提取内容,可以看到下面的程序最后一次提取是没有成功的,提取字符串用逗号分割会有问题,用空格可以,提取整型数据用逗号可以实现,用空格也可以实现
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main() {
char buf[] = "1 2 3";
int a, b, c;
//从buf中指定的格式提取内容
sscanf(buf, "%d %d %d", &a, &b, &c);
printf("a = %d,b=%d,c=%d",a, b, c);
printf("\n---------------------------------------------\n");
//提取整型变量是最方便的
char str[] = "a=1,b=2,c=3";
a = 0;
b = 0;
c = 0;
sscanf(str, "a=%d,b=%d,c=%d", &a, &b, &c);
printf("a = %d,b=%d,c=%d", a, b, c);
printf("\n---------------------------------------------\n");
char str2[] = "1;2;3";
a = 0;
b = 0;
c = 0;
sscanf(str2, "%d;%d;%d", &a, &b, &c);
printf("a = %d,b=%d,c=%d", a, b, c);
printf("\n---------------------------------------------\n");
char temp[] = "abc ren 434";
char m[10], n[10], o[10];
sscanf(temp, "%s %s %s", m, n, o);
printf("m = %s,n=%s,o=%s", m, n, o);
printf("\n---------------------------------------------\n");
char temp2[] = "abc,ren,434";
char m2[10], n2[10], o2[10];
sscanf(temp2, "%s,%s,%s", m2, n2, o2);
printf("m = %s,n=%s,o=%s", m2, n2, o2);
system("pause");
}
打印:
a = 1,b=2,c=3
---------------------------------------------
a = 1,b=2,c=3
---------------------------------------------
a = 1,b=2,c=3
---------------------------------------------
m = abc,n=ren,o=434
---------------------------------------------
m = abc,ren,434,n=烫烫烫烫烫烫烫烫烫烫abc,ren,434,o=烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫abc,ren,434请按任意键继续. . .
02.gets(已经不建议使用了)
#include <stdio.h>
char *gets(char *s)
从标准输入读取字符,并保存到s(一般是个数组,s是数组首地址)指定的内存空间,知道出现换行符或读取到文件结尾为止,和scanf不同之处,在于可以读取空格,有数组越界的风险,比如输入的大于数组的极限
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {
char buf[10];
gets(buf);
printf("%s\n", buf);
system("pause");
}
02.fgets(可以指定读取的大小,是安全的)
#include <stdio.h>
char *fgets(char *s,int size,FILE *stream);
从stream指定的文件流读入字符,保存到s所指定的内存空间,直到出现换行符都到文件结尾或是已读了size-1个字符为止,最后会自动加上字符'\0'作为字符串结束标志
#include <stdio.h>
int main() {
char buf[10];
//从stdin,也就是键盘输入流读取内容,如果输入内容大
//于sizeof(buf)-1,只读取sizeof(buf),注意它会把换行 符也读
//进去
fgets(buf, sizeof(buf), stdin);
printf("buf = %s\n", buf);
system("pause");
}
打印:
abcdefghijklmn
buf = abcdefghi
请按任意键继续. . .
03.puts(字符串输出到屏幕,类似printf)
include <stdio.h>
int puts(const char *)
标准设备输出字符串,在输出完成后,自动输出一个'\n',换行,注意字符串本身没有变化
#include <stdio.h>
int main() {
char buf[] = "hello";
//打印字符串buf,可以证明这个字符串本身是没有换行的
printf("buf = %s", buf);
//把buf内容输出到屏幕,自动在屏幕加换行,在屏幕加,字符串本身没变化
puts(buf);
//再次打印字符串,证明字符串本身没有变化
printf("buf = %s", buf);
system("pause");
}
打印
buf = hellohello
buf = hello请按任意键继续. . .
04.fputs(是puts的文件操作版本,但不会输出换行)
#include <stdio.h>
int fputs(const char *str,FILE *stream)
把指定内容输出到一个文件流中,puts是输出到屏幕,和puts区别在于它可以指定输出到哪个文件流,这个文件流也包括屏幕,只要将stream指定为stdout即可,并且不会在输出内容上加换行符
#include <stdio.h>
int main() {
char buf[] = "hello";
fputs(buf, stdout);
system("pause");
}
输出:
hello请按任意键继续. . .(没有换行)
05.strlen
#include<string.h>
size_t strlen (const char *s)
计算指定字符串s的长度,不包含字符串结束符'\0'(size_t为unsigned int 类型)
#include <stdio.h>
#include <string.h>
int main() {
char buf[] = "hello";
//strlen是从首元素开始,到结束符为止的长度,结束符不算
//到\0为止,所以如果手动加上了\0,比如he\0llo的strlen结果就是2
int len = strlen(buf);
printf("len = %d\n",len);
printf("sizeof(buf) = %d\n", sizeof(buf));
char buf2[] = "\0hello";
len = strlen(buf2);
printf("len2 = %d\n", len);
//sizeof测量的是数据类型的长度,不会因为结束符而提前结束,他的计算结果
//包括结束符,所以buf2的sizeof结果是7,因为最后还有一个结束符
printf("sizeof(buf2) = %d\n", sizeof(buf2));
system("pause");
}
打印:
len = 5
sizeof(buf) = 6
len2 = 0
sizeof(buf2) = 7
请按任意键继续. . .
6.strcpy
#include <string.h>
char *strcpy (char *dest,const char *src);
把src所指向的字符串复制到dest所指向的空间中,'\0也会拷贝过去',成功则返回dest字符的首地址,如果dest的空间不够大可能会溢出,当它复制的时候会从首地址开始,到\0结束,所以第二个打印只有一个hello输出
//因为不是安全的,所以要加上这个
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main() {
char src[100] = "hello world";
char dest[100];
strcpy(dest,src);
printf("dest = %s\n", dest);
char src2[100] = "hello\0 world";
char dest2[100];
strcpy(dest2, src2);
printf("dest2 = %s\n", dest2);
system("pause");
}
打印
dest = hello world
dest2 = hello
请按任意键继续. . .
7.strncpy(没有溢出的隐患,安全)
这个也会以\0结束,
#include <stdio.h>
#include <string.h>
int main() {
char src[100] = "hello world";
char dest[100];
//拷贝一个字符到dest
strncpy(dest,src,1);
printf("dest = %s\n", dest);
system("pause");
}
strcmp
#include <string.h>
char *strcmp(const char *s1,const char *s2);
比较s1和s2的大小,比较的是字符ASCII码大小,0表示相等,>0表示大于,小于0表示小于
#include <stdio.h>
#include <string.h>
int main() {
char s1[] = "abc";
char s2[] = "abcd";
int flag = strcmp(s1, s2);
if (flag == 0) {
printf("相等");
}
else if (flag > 0)
{
printf("s1 > s2");
}
else if (flag < 0)
{
printf("s1 < s2");
}
system("pause");
}
打印结果:s1<s2
strcnmp (可以指定比较的字符范围)
#include <stdio.h>
#include <string.h>
int main() {
char s1[] = "abc";
char s2[] = "abcdef";
int flag = strncmp(s1, s2,3);
if (flag == 0) {
printf("相等");
}
else if (flag > 0)
{
printf("s1 > s2");
}
else if (flag < 0)
{
printf("s1 < s2");
}
system("pause");
}
打印结果:相等
strcat 字符串追加
#define _CRT_SECURE_NO_WARNINGS //不安全
#include <stdio.h>
#include <string.h>
int main() {
char s1[] = "abc";
char s2[] = " defg";
strcat(s1, s2);
printf("%s\n",s1);
system("pause");
}
abc defg
请按任意键继续. . .
strncat 指定追加字符串的长度(也是不安全的,strncat_s是安全的)
严重性 代码 说明 项目 文件 行 禁止显示状态
错误 C4996 'strncat': This function or variable may be unsafe. Consider using strncat_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. 函数 c:\users\renzhenming\documents\visual studio 2015\projects\函数\函数\1.c 9
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main() {
char s1[] = "abc";
char s2[] = " defg";
strncat(s1, s2,strlen(" def"));
printf("%s\n",s1);
system("pause");
}
打印:abc def
sprintf 格式化字符串
严重性 代码 说明 项目 文件 行 禁止显示状态
错误 C4996 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. 函数 c:\users\renzhenming\documents\visual studio 2015\projects\函数\函数\1.c 16
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main() {
int a = 10;
char c = 'd';
char buf[] = "hello";
//格式化一个字符串,把这个字符串输出到屏幕
printf("a = %d, ch = %c , buf = %s \n",a,c,buf);
//格式化一个字符串,把这个字符串保存到指定的数组
char dest[100];
sprintf(dest, "a = %d, ch = %c , buf = %s \n", a, c, buf);
printf("%s\n",dest);
system("pause");
}
a = 10, ch = d , buf = hello
a = 10, ch = d , buf = hello
请按任意键继续. . .
strchr(在字符串s中查找字母c出现的位置)
#include <string.h>
char *strchr(const char *s ,int c);
#include <stdio.h>
#include <string.h>
int main() {
char buf[] = "abddddeee";
//在buf中查询字符d,如果找到,返回d所在位置的地址,如果打印p
//将得到从d所在位置开始到字符串结束的那个字符串
char *p = strchr(buf, 'e');
if (p == NULL) {
printf("查询失败\n");
}
else {
printf("p = %s\n",p);
}
system("pause");
}
strstr(在字符串haystack中查找needle出现的位置)
#include<string.h>
char *strstr(const char *haystack,const char *needle);
#include <stdio.h>
#include <string.h>
int main() {
char buf[] = "abddddeee";
//在buf中查询字符串,如果找到,返回d所在位置的地址,如果打印p
//将得到从d所在位置开始到字符串结束的那个字符串
char *p = strstr(buf, 'de');
if (p == NULL) {
printf("查询失败\n");
}
else {
printf("p = %s\n",p);
}
system("pause");
}
strtok字符串切割
#include <string.h>
char *strtok(char *str ,const char *delim)
用来将字符串切割成一个个片段,当strtok再参数s的字符串中发现参数delim中包含的分割字符时,则会将该字符改为\0字符,当连续出现多个时只替换第一个\0,这个函数是不安全的要加声明
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main() {
char buf[] = "hello,world,tomorrow";
//第一次调用,第一个参数写源字符串,第二个参数写切割字符
//返回值就是切割后的字符串,在匹配切割字符的地方,换成结束符,
char *p = strtok(buf,",");
printf("p=%s\n", p);
//使用strtok会破环原来的字符串结构,这时打印字符串得到的是切割后的
printf("buf=%s\n", buf);
printf("buf[5]=%d\n", buf[5]);
system("pause");
}
p=hello
buf=hello
buf[5]=0
请按任意键继续. .
第二次切割
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main() {
char buf[] = "hello,world,tomorrow";
//如果没有切割成功,返回NULL
char *p = strtok(buf,",");
printf("p1=%s\n", p);
//第二次调用,第一个参数写NULL
p = strtok(NULL, ",");
printf("p2=%s\n", p);
system("pause");
}
循环切割
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main() {
char buf[] = "hello,world,tomorrow";
//如果没有切割成功,返回NULL
char *p = strtok(buf,",");
while (p != NULL) {
printf("p = %s\n", p);
p = strtok(NULL, ",");
}
system("pause");
}
atoi
#include <stdlib.h>
int atoi(const char *ch);
atoi会扫描字符串ch,跳过前面的空格符,直到遇到正负号或数字才开始做转换(转换为数字),遇到非数字或字符串结束符\0才结束转换,并将结果返回
类似的函数有:
atof:把小数形式的字符串转换为float类型
atol:把一个字符串转化为long类型
#include <stdio.h>
#include <string.h>
int main() {
char buf[] = "-10";
printf("num = %d\n",atoi(buf));
system("pause");
}
网友评论