C语言 如何防止整数输入过界

Python014

C语言 如何防止整数输入过界,第1张

要防止整数输入过界可以考虑使用unsigned类的数据,范围会大一些。

long 或者 unsigned long 来满足更大范围的数据。

long long是C99标准里的,范围更大,或者unsigned long long不过很多编译器貌似不支持这种类型。。。

当然这里说的范围大只是相对的,还要看编译系统。

1.编程在一个已知字符串中查找最长单词,假定字符串中只含有字母和空格,空格用来分割不同单词!

方法一:

//VC++ 6.0 编译通过

#include

void main()

{

char str[]="hello world my name is xun yi cao !!"

char*p=str,*p1

int max=0,count=0,i

while(*p)

{

count=0

while(*p==' ')p++

while(*p!=' '&&*p)

{//一定要注意这里的判断 *p!=0 也要判断,不然到了最后一个单词时,它一直向后面加,直到碰见空格,所以会超界。

p++

count++

}

if(max<count)

{

max=count

p1=p-count

}

}

printf("the largest number is :%d \n",max)

printf("the largest word is : ")

while(*p1!=' '&&*p1) //这里也要判断*p1!='\0',因为如果最长的单词在字符串的末尾的话,如果不判断*p1!='\0',也会过界。

{

putchar(*p1)

p1++

}

putchar('\n')

}

/*

求字符串中最长的单词。要注意的是:如果在一个循环A 里面还有循环B 的话。那么不仅在循环B里面要保证,数组不过界。

而且要要保证在循环A里面数组也不过界。就像上面的例子一样。现给出一个更容易理解的例子。

while(*p)

{

while(*p!=' '&&*p)

{

p++

}

}

虽然外循环和内循环在循环条件上没有什么必然的联系,但是对于一个数组的指针而言(如果以变量下标的

形式来访问数组的话,下标的加减也要引起注意),它的加减也要引起注意,必须要保证不能过界。

*/

方法二:

//VC++ 6.0 编译通过。

#include

#include

void main()

{

char str[]=" I am a student"

char*p=str,Array[10][20]={0}

int i=0,j=0,max=0

while(*p)

{

while(*p==' ')*p++

while(*p&&*p!=' ')

{

Array[i][j++]=*p

p++

}

i++j=0

}

i=0

max=strlen(Array[i])

p=Array[i]

while(strlen(Array[i]))

{

if(max<strlen(Array[i]))

{

max=strlen(Array[i])

p=Array[i]

}

i++

}

printf("%d\n%s\n",max,p)

}

/*

求字符串中最长的单词(不能分辨含非字母字符的单词),采用的是二维数组的形式判断的。

定义了一个二维数组,它的每一个元素用来存放一个字符串(每个被分离后的单词)。

再判断最长的那个。

这中方法对比第一种方法来说,思路更清晰一些。但是缺点就是要分配一个二维的数组来存放被分离后的每个

单词,占用存储空间。

*/

2.编写实现任意十进制数,转换成r进制数(r在2到16之间)

转换为二进制:

//VC++ 6.0编译通过

#include

#include

void main()

{

int a,b[30],i

scanf("%d",&a)

for(i=0a!=0i++)

{

b[i]=a%2

a=a/2

}

for(--ii>=0i--)

{

printf("%d",b[i])

}

putchar('\n')

}

//关于二进制的转换,还可以用位移运算符。通过和某一个数如1相按位与,就得到它的二进

制最低位,在位移,再得到二进制最低位,依此类推。

转换为8进制:

/VC++ 6.0编译通过。

#include

#include

void main()

{

int a,b[20],i

scanf("%d",&a)

for(i=0a!=0i++)

{

b[i]=a%8

a=a/8

}

for(--ii>=0i--)

{

printf("%d",b[i])

}

putchar('\n')

}

/*

转换为8进制就没有16进制那么麻烦了,它不需要另外定义一个字符数组用来存放,进制的

所有基数了,而是直接输出来就可以了。而对与16进制还要存放他的基数。从0到F

*/

转换为16进制:

//VC++ 6.0 下编译通过

#include

#include

void main()

{

int a,b[20],i,base=16

char X[16]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}

scanf("%d",&a)

for(i=0a!=0i++)

{

b[i]=a%base

a=a/base

}

for(--ii>=0i--) //开始有一个 --i

{

int j=b[i]

printf("%c",X[j])

}

printf("\n")

}

/*

一般把其它进制的数转换为十进制的数较容易,有一个现成的乘法公式供我们使用。

但把十进制的数转换为其它进制的数,则要用到除法。这题的思路是比较清晰的,应该是

解决这类问题的典型算法了。

而对于把十进制的数转换为二进制的数来说,除了用到除法外,还可用位运算。

这个问题主要是这两句话值得理解:

b[i]=a%base

a=a/base

我们一般是用这两句循环使用来得到一个整数的各位的数字,这也恰巧说明了,我们得到

一个整数的各个位数所用到的方法,正是把一个十进制的数转换为一个 "十进制" 数的算法

也就是我们得到一个十进制数的各个位的数字的过程,实际上就是求把他转换为一个十进制

的数字的过程(虽然这里本身没必要在转换,因为本身它就已经是一个十进制数了)。用同样

的道理可以推算把十进制数转换为其他进制数的过程,和这个是类似的。

然后将后得到的结果先输出,而先取余数得到的结果则在数字的最后面,在低位。

*/

通用解决方案:

#include

#include

void main()

{

int a[10]={0,1,2,9,10,5,12,7,8,15}

for(int i=9i>=0i--)

{

if(a[i]>=10)

switch(a[i])

{

case 10: printf("%c",'A')break

case 11: printf("%c",'B')break

case 12: printf("%c",'C')break

case 13: printf("%c",'D')break

case 14: printf("%c",'E')break

case 15: printf("%c",'F')break

}

else

printf("%d",a[i])

}

}

/*

其实进制转换的算法我们都知道,就是用我们要转换的那个数,对进制的基数(如果是16进制)

进行取余,把取余的结果保存在一个数组里面,再对他取整重新赋值,也就是丢掉余数部分,

相当于取上一步的商,再取余,再取整。如此循环,直到为0。

其实上面的算法,只要我们想起把一个十进制的数转换为二进制的数的计算方法,就不难理解,

因为都是相通的。

现在关键是,如果我的这些事情都做好了,也就是余数都放在一个数组里了,现在要做的就是

把数组逆序输出就ok了。那么如果是二进制或八进制,我们只要直接输出就可以了,但是如果是

一个十六进制的话,就不能这样了,也就是如果数组里面有一个元素是14,那么我就不能原样输出

了,此时必须输出E,因为E就是十六进制里面的基数,而且也是与十进制的14相对应的。但是如果

是一个二进制或者是一个八进制的话,就可以直接输出,因为数组里面的数都是0,1(对二进制)

或者(0....8),这些数就是二进制和八进制的基数。

所以这里要面临的问题就是,在输出一个整数的时候,如果这个整数满足某一条件,就输出什么字

符的问题,例如:如果这个整数等于14则输出'E'字符。

当然我们可以用 if..else 语句来判断,对于十六进制的数特殊的字符也就只有A,B,C,D,E,F六个

用 if...else 来判断也不算太烦琐。当然我们还可以用 switch 来判断,这样更加有条理。代码

也更清晰。

当然这是对于16进制的数来说的,我们可以这样判断,但是如果实际生活中遇到的问题和这个有点

类似,而且字母有多的话,用条件判断或switch就太烦琐了,代码也不直观,还容易出错。

那么这时我们可以在定义一个字符数组,分别放我们要输出的字符,如果有以下对应的关系:

10 A

11 B

12 C

13 D

14 E

15 F

16 G

17 H

18 I

19 J

也就是说在数组a里面放的是数字,在数组b里面放的是字符,要求数组a里面的数字是10的时候,输

出'A',而不是输出10,依次类推(看上面的对应关系),当然我上面的对应关系都是顺序的,其实也

可以不是顺序的,对于数字和字符都可以是乱的,当然这要看实际遇到的问题是什么样的了。如果

对上面的问题还用if...else来判断的话,那未免太烦琐。所以我们定义一个字符数组来专门存放

字符。那么怎么让数字和字符联系起来呢,怎么让a[i]的值是10的时候就输出'A'而是14的时候就输

出'E'呢,在这里我们可以这样定义b数组:

char b[30]={0}

b[10]='A'

b[11]='B'

b[12]='C'

b[13]='D'

b[14]='E'

...

b[19]='J'

这样也就是说当a[i]元素的值是10时,就输出b[10],是11就输出b[11];这样就和数字对应起来

了。我们可以这样用:

int t=a[i]

printf("%c",b[t])a[i]的值是多少,我们就输出b[多少]

但对于上面举的例子来说,可以这样:

if(a[i]>=10&&a[i]<=19) //对应关系是连续的,才可以这样判断

{

int t=a[i]

printf("%c",b[t])

}

else

{

printf("%d",a[i])//如果不属于定义的对应的特殊字符,就原样输出。

}

当然了,上面的是对应的连续的情况,对与10进制与二进制,8进制,16进制之间的转换,都是连续的情况。

如果对应的是不连续的情况,那有该怎么办呢:

20 'A'

25 'B'

30 'D'

50 'G'

53 'H'

58 'C'

100 'Z'

200 'W'

对于上面的情况,是一点规律性也没有的,而且如果为了这几个数就去定义一个200个元素的数组,实在是

有点划不来。所以如果是上面这种情况,就没有比较好的办法了。只用用判断语句了,当然如果有20多个

字符的对应关系的话,判断语句也是不合适的,那么就没有比较好的办法了。还要进一步探索....

*/

这些都是我在考计算机等级考试碰到过的题目哦,算法都是相当典型的,有的是书上看到的,有的是自己扩展的。还是要自己认真哦。。。

由于文字太多第三题提交不上来了哦。。不好意思。。。

1.编程在一个已知字符串中查找最长单词,假定字符串中只含有字母和空格,空格用来分割不同单词!

方法一:

//VC++ 6.0 编译通过

#include<stdio.h>

void main()

{

char str[]="hello world my name is xun yi cao !!"

char*p=str,*p1

int max=0,count=0,i

while(*p)

{

count=0

while(*p==' ')p++

while(*p!=' '&&*p)

{//一定要注意这里的判断 *p!=0 也要判断,不然到了最后一个单词时,它一直向后面加,直到碰见空格,所以会超界。

p++

count++

}

if(max<count)

{

max=count

p1=p-count

}

}

printf("the largest number is :%d \n",max)

printf("the largest word is : ")

while(*p1!=' '&&*p1) //这里也要判断*p1!='\0',因为如果最长的单词在字符串的末尾的话,如果不判断*p1!='\0',也会过界。

{

putchar(*p1)

p1++

}

putchar('\n')

}

/*

求字符串中最长的单词。要注意的是:如果在一个循环A 里面还有循环B 的话。那么不仅在循环B里面要保证,数组不过界。

而且要要保证在循环A里面数组也不过界。就像上面的例子一样。现给出一个更容易理解的例子。

while(*p)

{

while(*p!=' '&&*p)

{

p++

}

}

虽然外循环和内循环在循环条件上没有什么必然的联系,但是对于一个数组的指针而言(如果以变量下标的

形式来访问数组的话,下标的加减也要引起注意),它的加减也要引起注意,必须要保证不能过界。

*/

方法二:

//VC++ 6.0 编译通过。

#include<stdio.h>

#include<string.h>

void main()

{

char str[]=" I am a student"

char*p=str,Array[10][20]={0}

int i=0,j=0,max=0

while(*p)

{

while(*p==' ')*p++

while(*p&&*p!=' ')

{

Array[i][j++]=*p

p++

}

i++j=0

}

i=0

max=strlen(Array[i])

p=Array[i]

while(strlen(Array[i]))

{

if(max<strlen(Array[i]))

{

max=strlen(Array[i])

p=Array[i]

}

i++

}

printf("%d\n%s\n",max,p)

}

/*

求字符串中最长的单词(不能分辨含非字母字符的单词),采用的是二维数组的形式判断的。

定义了一个二维数组,它的每一个元素用来存放一个字符串(每个被分离后的单词)。

再判断最长的那个。

这中方法对比第一种方法来说,思路更清晰一些。但是缺点就是要分配一个二维的数组来存放被分离后的每个

单词,占用存储空间。

*/

2.编写实现任意十进制数,转换成r进制数(r在2到16之间)

转换为二进制:

//VC++ 6.0编译通过

#include<stdio.h>

#include<string.h>

void main()

{

int a,b[30],i

scanf("%d",&a)

for(i=0a!=0i++)

{

b[i]=a%2

a=a/2

}

for(--ii>=0i--)

{

printf("%d",b[i])

}

putchar('\n')

}

//关于二进制的转换,还可以用位移运算符。通过和某一个数如1相按位与,就得到它的二进

制最低位,在位移,再得到二进制最低位,依此类推。

转换为8进制:

/VC++ 6.0编译通过。

#include<stdio.h>

#include<string.h>

void main()

{

int a,b[20],i

scanf("%d",&a)

for(i=0a!=0i++)

{

b[i]=a%8

a=a/8

}

for(--ii>=0i--)

{

printf("%d",b[i])

}

putchar('\n')

}

/*

转换为8进制就没有16进制那么麻烦了,它不需要另外定义一个字符数组用来存放,进制的

所有基数了,而是直接输出来就可以了。而对与16进制还要存放他的基数。从0到F

*/

转换为16进制:

//VC++ 6.0 下编译通过

#include<stdio.h>

#include<string.h>

void main()

{

int a,b[20],i,base=16

char X[16]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}

scanf("%d",&a)

for(i=0a!=0i++)

{

b[i]=a%base

a=a/base

}

for(--ii>=0i--) //开始有一个 --i

{

int j=b[i]

printf("%c",X[j])

}

printf("\n")

}

/*

一般把其它进制的数转换为十进制的数较容易,有一个现成的乘法公式供我们使用。

但把十进制的数转换为其它进制的数,则要用到除法。这题的思路是比较清晰的,应该是

解决这类问题的典型算法了。

而对于把十进制的数转换为二进制的数来说,除了用到除法外,还可用位运算。

这个问题主要是这两句话值得理解:

b[i]=a%base

a=a/base

我们一般是用这两句循环使用来得到一个整数的各位的数字,这也恰巧说明了,我们得到

一个整数的各个位数所用到的方法,正是把一个十进制的数转换为一个 "十进制" 数的算法

也就是我们得到一个十进制数的各个位的数字的过程,实际上就是求把他转换为一个十进制

的数字的过程(虽然这里本身没必要在转换,因为本身它就已经是一个十进制数了)。用同样

的道理可以推算把十进制数转换为其他进制数的过程,和这个是类似的。

然后将后得到的结果先输出,而先取余数得到的结果则在数字的最后面,在低位。

*/

通用解决方案:

#include<stdio.h>

#include<string.h>

void main()

{

int a[10]={0,1,2,9,10,5,12,7,8,15}

for(int i=9i>=0i--)

{

if(a[i]>=10)

switch(a[i])

{

case 10: printf("%c",'A')break

case 11: printf("%c",'B')break

case 12: printf("%c",'C')break

case 13: printf("%c",'D')break

case 14: printf("%c",'E')break

case 15: printf("%c",'F')break

}

else

printf("%d",a[i])

}

}

/*

其实进制转换的算法我们都知道,就是用我们要转换的那个数,对进制的基数(如果是16进制)

进行取余,把取余的结果保存在一个数组里面,再对他取整重新赋值,也就是丢掉余数部分,

相当于取上一步的商,再取余,再取整。如此循环,直到为0。

其实上面的算法,只要我们想起把一个十进制的数转换为二进制的数的计算方法,就不难理解,

因为都是相通的。

现在关键是,如果我的这些事情都做好了,也就是余数都放在一个数组里了,现在要做的就是

把数组逆序输出就ok了。那么如果是二进制或八进制,我们只要直接输出就可以了,但是如果是

一个十六进制的话,就不能这样了,也就是如果数组里面有一个元素是14,那么我就不能原样输出

了,此时必须输出E,因为E就是十六进制里面的基数,而且也是与十进制的14相对应的。但是如果

是一个二进制或者是一个八进制的话,就可以直接输出,因为数组里面的数都是0,1(对二进制)

或者(0....8),这些数就是二进制和八进制的基数。

所以这里要面临的问题就是,在输出一个整数的时候,如果这个整数满足某一条件,就输出什么字

符的问题,例如:如果这个整数等于14则输出'E'字符。

当然我们可以用 if..else 语句来判断,对于十六进制的数特殊的字符也就只有A,B,C,D,E,F六个

用 if...else 来判断也不算太烦琐。当然我们还可以用 switch 来判断,这样更加有条理。代码

也更清晰。

当然这是对于16进制的数来说的,我们可以这样判断,但是如果实际生活中遇到的问题和这个有点

类似,而且字母有多的话,用条件判断或switch就太烦琐了,代码也不直观,还容易出错。

那么这时我们可以在定义一个字符数组,分别放我们要输出的字符,如果有以下对应的关系:

10 A

11 B

12 C

13 D

14 E

15 F

16 G

17 H

18 I

19 J

也就是说在数组a里面放的是数字,在数组b里面放的是字符,要求数组a里面的数字是10的时候,输

出'A',而不是输出10,依次类推(看上面的对应关系),当然我上面的对应关系都是顺序的,其实也

可以不是顺序的,对于数字和字符都可以是乱的,当然这要看实际遇到的问题是什么样的了。如果

对上面的问题还用if...else来判断的话,那未免太烦琐。所以我们定义一个字符数组来专门存放

字符。那么怎么让数字和字符联系起来呢,怎么让a[i]的值是10的时候就输出'A'而是14的时候就输

出'E'呢,在这里我们可以这样定义b数组:

char b[30]={0}

b[10]='A'

b[11]='B'

b[12]='C'

b[13]='D'

b[14]='E'

...

b[19]='J'

这样也就是说当a[i]元素的值是10时,就输出b[10],是11就输出b[11];这样就和数字对应起来

了。我们可以这样用:

int t=a[i]

printf("%c",b[t])a[i]的值是多少,我们就输出b[多少]

但对于上面举的例子来说,可以这样:

if(a[i]>=10&&a[i]<=19) //对应关系是连续的,才可以这样判断

{

int t=a[i]

printf("%c",b[t])

}

else

{

printf("%d",a[i])//如果不属于定义的对应的特殊字符,就原样输出。

}

当然了,上面的是对应的连续的情况,对与10进制与二进制,8进制,16进制之间的转换,都是连续的情况。

如果对应的是不连续的情况,那有该怎么办呢:

20 'A'

25 'B'

30 'D'

50 'G'

53 'H'

58 'C'

100 'Z'

200 'W'

对于上面的情况,是一点规律性也没有的,而且如果为了这几个数就去定义一个200个元素的数组,实在是

有点划不来。所以如果是上面这种情况,就没有比较好的办法了。只用用判断语句了,当然如果有20多个

字符的对应关系的话,判断语句也是不合适的,那么就没有比较好的办法了。还要进一步探索....

*/

这些都是我在考计算机等级考试碰到过的题目哦,算法都是相当典型的,有的是书上看到的,有的是自己扩展的。还是要自己认真哦。。。

由于文字太多第三题提交不上来了哦。。不好意思。。。