c语言==字符串的键入,遍历,输出(6)

来源:互联网 发布:网络安全法的重要性 编辑:程序博客网 时间:2024/04/30 00:31

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 1024int 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 = 2num = (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变成19i = (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保存到了首地址,可以直接输出了。
0 0
原创粉丝点击