c语言==字符串的键入,遍历,输出(6)
2016-07-14 14:18
274 查看
atoi函数
c语言中,atoi函数将字符串转变为数字,若遇到字母,就会停止输出#include <stdio.h> #define Max_size 1024 #include <string.h> void atoi(char *a) { int temp = 0; int i = 0; int flag = 1; if(a[i] == '-') { flag = -1; } while(a[i] != 0) { if(a[i] > '0' && a[i] < '9') { temp = a[i] - '0' + temp * 10; i++; } else break; } printf("%d\n" , temp * flag); } int main() { char a[Max_size]; printf("请输入字符串\n"); scanf("%s" , a); atoi(a); return 0; }
这个程序完成了从字符串变为数字的功能
思想算法:
首先要得到一串字符串,所以要创建一个字符数组用来存放。然后依次将这个数组里的字符遍历得到,通过一些方法,将得到的那些数转化为十进制。
tips:
1、要输入一串字符串,就要通过字符数组来存放
2、字符数组里的0相当于’\0’
3、在定义数组的时候,可以运用宏定义去实现给他分配多少空间
4、在atoi函数中,形参为字符数组,则要加上*,即取数组首地址
5、一串字符串也很有可能是负的,所有要先定义他的一个标志位flag,然后判断他的首位是否为负,为负的话就令flag为-1,然后在最后的结果的基础上乘以flag。
6、在字符数组没有读到空之前,都要一直向后读数,因为不知道有多少次,所以用while,判断条件为a【i】是否等于0(参见tip2),比用strlen方便的多
7、也可以不用数组i来进行判断,用*加数组名,来代表首地址,并读出里面的内容。然后数组名++就代表依次向后移位。例如
if(*a == '-') { flag = -1; a++; } while(*a != 0) { a++; }
8、atoi这个函数默认的输入数字才有效,输入字母自动退出,而输出前面的数。所以要对字符数组的内容进行判断是否是数字
9、得到数字之后,要将他转化为十进制。因为他是先得到的高位数,所以可以让她连着低位数一起乘10,有多少位乘以多少10
问:什么叫格式化输出与输入
答:在输出与输入时,会有格式的限定。如果不按照程序里规定的格式输入,则会出现未知数。#include <stdio.h> int main() { int i; printf("请输入一个整数\n"); scanf("sm = %d" , &i); printf("%d\n" , i); return 0; }
这个程序在输入的时候就应该输入 sm = 3,必须按照他给你的格式进行输入,否则就会出现未知数,而程序也会乖乖的按照既定的格式进行输出。
#include <stdio.h> int main() { int i; int num; int c_num; float f_num; double d_num; int a[3]; char src[3]; printf("请输入整型数\n"); scanf("%d" , &num); printf("num = %d\n" , num); getchar(); printf("请输入字符型数\n"); scanf("%c" , &c_num); printf("c_num = %c\n" , c_num); printf("请输入浮点型数\n"); scanf("%f" , &f_num); printf("f_num = %f\n" , f_num); printf("请输入长浮点型数\n"); scanf("%lf" , &d_num); printf("d_num = %lf\n" , d_num); printf("请输入整型数组数\n"); for(i = 0; i < 3; i++) { scanf("%d" , &a[i]); } printf("数组为:\t"); for(i = 0; i < 3; i++) { printf("%d\t" , a[i]); } printf("\n"); printf("请输入字符串\n"); scanf("%s" , src); printf("字符串为:%s\n" , src); return 0; }
这个程序包括了许多典型数据类型的输入和输出,其中有一个很特殊,就是字符型数的输入。
他会自动捕获在键盘上get到的字符类型。在输入完整型数之后,自然的会敲一个回车键,如果不做任何操作,字符型数就会默认回车是键入的字符,所以,在两者之间要加入一个getchar()操作。去回收那个回车键。并且让程序能够停下来等待字符型数的键入。
问: 键入字符串有什么方法?
答:一共有三种方法1、scanf
2、gets
3、getchar
首先
scanf的形式是scanf(“%s” , a);但是他遇到空格就会停止读入,只输出空格前的东西。
百度了一下,发现有一个博主说是先让程序sleep,然后还分了几个字符串输出的
scanf()函数不能正确接受有空格的字符串?如: I love you!
#include <stdio.h> int main() { char str[80]; scanf("%s",str); printf("%s",str); return 0; }
输入:I live you!
输出:I
scanf()函数接收输入数据时,遇以下情况结束一个数据的输入:(不是结束该scanf函数,scanf函数仅在每一个数据域均有数据,并按回车后结束)。
① 遇空格、“回车”、“跳格”键。
② 遇宽度结束。
③ 遇非法输入。
所以,上述程序并不能达到预期目的,scanf()扫描到”I”后面的空格就认为对str的赋值结束,并忽略后面的”love you!”.这里要注意是”love you!”还在键盘缓冲区(关于这个问题,网上我所见的说法都是如此,但是,我经过调试发现,其实这时缓冲区字符串首尾指针已经相等了,也就是说缓冲区清空了,scanf()函数应该只是扫描stdin流,这个残存信息是在stdin中)。我们改动一下上面的程序来验证一下:
#include <stdio.h> int main() { char str[80]; char str1[80]; char str2[80]; scanf("%s",str);/*此处输入:I love you! */ printf("%s",str); sleep(5);/*这里等待5秒,告诉你程序运行到什么地方*/ scanf("%s",str1);/*这两句无需你再输入,是对键盘盘缓冲区再扫描 */ scanf("%s",str2);/*这两句无需你再输入,是对键盘盘缓冲区再扫描 */ printf("/n%s",str1); printf("/n%s",str2); return 0; }
输入:I love you!
输出:I
love
you!
好了,原因知道了,那么scanf()函数能不能完成这个任务?回答是:能!别忘了scanf()函数还有一个 %[] 格式控制符
然后
gets的格式是gets(a);他可以得到一个句子,即输入的两个字符串之间有空格也没有关系。但是值得注意的是,如果上下类型不一致,需要加上getchar(),而scanf就不需要。另外,gets这个函数十分危险,因为他就算越界了,他也可以正常输出。
例如:
假设数组msg[40]是取40个字符,输入helloworld能够在屏幕上正常回显输出。但若是把40改为2,输入helloworld屏幕上也能正常回显输出,感觉此时数组应该越界了。
问题:
1、越界了能正常输出?数组msg[2]不会把字符串截断吗?
2、能正常输出的话,那么字符数组msg[40]定义的40就可以定义成任何数了,字符数组里的数限制不了字符数组的长度。我见过一些程序一般是把数组设置的足够大,只能用这种方法防止越界?有没有其他方法如果越界了的话能给与提示。
3、在网上看到gets函数很危险,不推荐使用。推荐fgets函数,但fgets函数是从文件输入的字符串。我现在想实现从键盘输入字符串存到数组里的功能,但又想避免越界。有没有好的方法?
最后,
getchar的格式是getchar();一个字符一个字符的读,虽然有点慢,但是能够防止溢出。
这种一个个输字符的函数,还可以输入密码,密码用*替代。
#include <stdio.h> #define Max_size 1024 int main() { int i = 0; char ch; char a[Max_size]; while((ch = getchar()) != '\n') { printf("*"); } return 0; }
这个程序输出的就是各种*代替密码的显示
tips:
1、while(1) 代表的是,函数一直不会停止;2、exit(1)代表的是,退出这个函数;
3、数组名代表的是数组首元素的地址,a+i代表的是a[0],a[1],a[2]
输出的时候,*(a+i)就可以取内容了
danger:数组名是一个常量,不可以自加,如a++,只可以写a+i
但是如果用一个p指针指向数组,那么p是可以自增的。
another danger:如果在输入的时候。一直用的p++,那么输出的时候,必须先把p指向a[0],因为输完了的时候p在最后。
4、打印字符串,用puts(),打印字符型数,用putchar();
打印p指针,printf(“p = %p\n” , &num );
打印无符号整型 %u
printf是行缓冲区,需要有\n才能输出
但是也有输出的特例,比如1、程序结束了,清除缓冲区的时候会输出
2、当紧跟着printf之后又有一个scanf的时候,由于他们用的是同一个行缓冲区,所以会输出出来。
但是当这个程序一直不停止,如while(1)的时候,printf就会不出来
警告:返回一个局部变量的地址的处理方法
有时会在一个函数里面定义一个局部变量。并且将它作为返回值,这时就会出现警告,因为返回的是一个局部变量的地址。所以一般会在这个变量前面加上static。将字符串逆序输出
int i; char temp; for(i = 0; i < len / 2; i++) { temp = a[i]; a[i] = a[len-i-1]; a[len-i-1] = temp; }
关于i++及++i
i++:先用再自增++i :先自增再用
例如:
int i = 2 num = (i++)+(i++)+(i++)+(i++); //num = 2 + 2 + 2 + 2 = 8 i = 6; //因为i++是先用再自增,所以他会一直运用到结束符(分号)再停止。 num = (++i) + (++i) + (++i) + (++i); //num = 4 + 4 + 5 + 6 = 19 i = 6 //前面两个是4的原因:运算操作符要有两个才可以做,所以先+1,+1变成4再加。 i = i * ((i++)+(++i)); //先算括号,又是一个运算符,所以要把后面的++i也算完了才能确定前面的i++,即2赋过去,遇到i++先不自加,然后++i的时候+1,变成3,这时候两个都变成3了,然后还有一个i没有乘,所以还是乘以3,最后遇到分号的时候完成i++,i = 18之后再加1变成19 i = (i++) + (++i) +(i++) + (++i); //先把2赋过去,不自增,但是由于运算符,要等第二个数,++i自增一个,变成3,这时候3 + 3, 然后再加3,不自增,遇到++i,变成4 加上4,遇到分号再把刚才两个自增加上去 即i = 3+3+3+4+2 = 15; //还有作为函数实参的情况 //函数是从右边开始传参的,逗号,分号,函数括号都是结束标志。 //++i被替换成变量名i,i++直接被替换成数值。 show(++i,++i,i++,++i,i++); //先从右边开始读,i++直接变成2,遇到逗号,i = 3,然后++i,先变成i,这时候i = 4,然后i++,是4,遇到逗号,i=5,然后++i,先变成i,i = 6,然后++i,再变成i,i = 7,这时候把所有的i都用7来替换,即7 7 4 7 2 //show(i++,++i,i,i++,++i); //5 i i 3 i //i=6 i=5 i=4 i=4 i=3 //所以结果是5 6 6 3 6
数组和指针
数组名是一个常量,用来保存首元素的地址。由于数组名是一个常量。所以不可以将一个值赋给数组名,试图将内容保存到数组里。
而指针是一个变量,可以将一个值赋给指针名。
char temp[MAX_SIZE]; temp = my_strcpy(dest,src); //这个方法是错的,因为这个函数他返回的是数组首地址(或字符串首地址),不可以赋给一个常量(数组名) char * temp; temp = my_strcpy(dest,src); //此方法是对的,因为返回的是一个地址,所以要把他存在指针里,所以定义一个temp指针,然后将他赋给这个变量(指针名) //由此可见,在定义my_strcpy这个函数的时候,他的返回类型肯定是一个地址类型,即指针类型。如下 char * my_strlen(char * dest, char * src) //其次,这个想要输出这个temp内容的时候,格式如下 printf("%s" , temp); //因为temp保存到了首地址,可以直接输出了。
相关文章推荐
- 如何组织构建多文件 C 语言程序(二)
- 如何写好 C main 函数
- Mootools 1.2教程 函数
- autoit InputBox 函数
- 文件遍历排序函数
- 关于C#中排序函数的总结
- Oracle 函数大全[字符串函数,数学函数,日期函数]第1/4页
- ASP下经常用的字符串等函数参考资料
- PostgreSQL教程(五):函数和操作符详解(1)
- DOS批处理 函数定义与用法
- asp Chr 函数 数字转字母的方法
- Lua中的函数精讲笔记
- Lua 学习笔记之C API 遍历 Table实现代码
- Lua中的闭合函数、非全局函数与函数的尾调用详解
- Lua中调用C++函数示例
- Lua和C语言的交互详解
- Lua实现split函数
- Lua常用时间函数使用实例
- Lua函数与字符串处理简明总结