|
bush
银牌会员
积分 2165
发帖 730
注册 2004-4-21
状态 离线
|
|
2004-6-20 00:00 |
|
|
bush
银牌会员
积分 2165
发帖 730
注册 2004-4-21
状态 离线
|
『第
2 楼』:
原来的
程序是:
main(c){putch(isalpha(c)? tolower(c)<'n'? c+13: c-13: c);}
只处理英文字母!
|
|
2004-6-20 00:00 |
|
|
Kinglion
铂金会员
痴迷DOS者
积分 5792
发帖 1921
注册 2003-6-20 来自 金獅電腦軟體工作室
状态 离线
|
『第
3 楼』:
支持原创!
|
熟能生巧,巧能生精,一艺不精,终生无成,精亦求精,始有所成,臻于完美,永无止境!
金狮電腦軟體工作室愿竭诚为您服务!
QQ群:8393170(定期清理不发言者)
个人网站:http://www.520269.cn
电子邮件:doujiehui@vip.qq.com
微信公众号: doujiehui
|
|
2004-6-20 00:00 |
|
|
jihao1234567
中级用户
积分 258
发帖 58
注册 2003-10-11
状态 离线
|
『第
4 楼』:
唔,楼主强大……但是我不会C………………
|
奋发向上!!! |
|
2004-6-21 00:00 |
|
|
willsort
元老会员
Batchinger
积分 4432
发帖 1512
注册 2002-10-18
状态 离线
|
『第
5 楼』:
Re bush:
同 Kinglion 兄,支持原创,本版的优秀代码仍然是"物以稀为贵"的,可惜水平有限,心有余而力不足。
楼主的代码没有什么大问题,只是作为一个加密程序来说,功能还是略显不足了些。再提一个小建议,while((c=getc(in))+1) 我认为还是改为 while((c=getc(in)) != EOF) 好些,因为EOF是标准的一部分,而-1却不是。类似的技巧,虽然可以体现编程者的机智,但仍然少用为妙。
另有一个疑惑,我知道c&0x40是判断字母表以上的字符,但是c&0x1f是什么意思呢?
[此贴子已经被作者于2004-6-21 下午 07:58:35编辑过]
|
※ Batchinger 致 Bat Fans:请访问 [讨论]批处理编程的异类 ,欢迎交流与共享批处理编程心得! |
|
2004-6-21 00:00 |
|
|
bush
银牌会员
积分 2165
发帖 730
注册 2004-4-21
状态 离线
|
『第
6 楼』:
好!
我之所以要用位操作取代标准函数,是因为isalpha(c)和 tolower(c) 在当c是非ascii字符时,会产生不合理的结果。
字母表以上的字符共同点都是第五位为‘1’;但c&0x40还不足以判断字母表的字符,因为还有几个符号第五位也为‘1’;如果像原来的英文程序上,用tolower(c)判断是否小于'n',则会把后面那几个符号误认为是大于'n'的字母。
同时:tolower() 不会对最高位为1的符号(汉字就是)处理;c&0x1f是为了对两种情况(ascii字符和非ascii字符)一视同仁地处理。后面就可以比大小决定是向前rot13还是向后rot13.
|
|
2004-6-22 00:00 |
|
|
willsort
元老会员
Batchinger
积分 4432
发帖 1512
注册 2002-10-18
状态 离线
|
『第
7 楼』:
/*
Will Sort 改编注:
本程序根据 “中国DOS联盟之联合DOS论坛 → DOS开发编程 & 发展交流 (开发室)
→ 浏览:[分享]我写的ROT13加编/解码程序! ”一文中所附的程序改编。欢迎原作者
bush 和其他爱好者提出宝贵意见。
改编摘要:
1,exit函数改为return语句
使用exit需要包含stdlib.h,而return关键字也可实现同样功能;
2,while((c=getc(in))+1)改为while((c=fgetc(in)) != EOF)
tc中getc为宏,fgetc为函数,都调用底层io函数,虽然getc较为高效,但是文件
函数惯常使用f为首字母;
-1(即 EOF,tc中定义的文本文件结束符的常数, 某些函数读取错误也会返回此
值)的用法不值得鼓励,因为它并非标准c定义的内容,在其他c编译系统中可能出现编
译错误;
3,位运算改为逻辑运算
位运算其高效性值得怀疑;而作者所说的不合理也并非因为ctype函数,而是 char
这个变量类型,几乎所有的IO函数都是返回和调用int 型字符的,因为char 的界限是
0-127,所以getc返回的非ascii值都只保存了其低7位的值,导致作者所说的问题。而
作者所说的对中文的处理似乎并非原文输出,也非对所有中文字符绕转,而只是对某些
中文字符进行处理,这样做的意义何在?这里改用逻辑运算的原因在于,实现此简单的
功能无需付出额外的包含ctype.h的代价。
4,char c,temp改为int c, temp
参见3
5,一些书写风格上的改变
无它,习惯而已。
用TC编写,大小9.84kB,可以用来对文本文件加密。大家可以来试一下,看看有没有什么问
题,rot13.exe 压缩包
用法是 rot13 源文件 编码文件
但不要使两个参数同名。
ROT13 是一种简单的编码,它把字母分成前后两组,每组13个,编码和解码
的算法相同,仅仅交换字母的这两个部分。
我发现标准的程序无法正确地处理中文,原因好像是几个ctype.h标准函数处理非ASCII字符
不太严密
所以我重写了一个,可以处理中文,
以下是源代码:
*/
#include
int main(int argc,char*argv[]) {
FILE *in, *out;
int c;
if (argc= 'a' && c = 'A' && c = 'n' && c = 'N' && c <= 'Z')
putc(c-13, out);
else
putc(c, out);
}
/*putch(isalpha(c)? tolower(c)<''n''? c+13: c-13: c);*/
return 0;
}
|
※ Batchinger 致 Bat Fans:请访问 [讨论]批处理编程的异类 ,欢迎交流与共享批处理编程心得! |
|
2004-7-11 00:00 |
|
|
bush
银牌会员
积分 2165
发帖 730
注册 2004-4-21
状态 离线
|
『第
8 楼』:
to Will Sort:
我所说的不用ctype函数,并非只是 因为“char其低7位的值”原因(如果是那样,程序是很好处理的):
举例说明一下:
#include
int main()
{
char s[]="你好";
int i=0;
char c;
for(;i<4;i++)
printf("%c %s\n",s,isalpha(s)? " is a letter.":" not letter."
for(i=0;i<4;i++)
printf("%c %s\n",s,islower(s)? " is a lowercase letter.":" not a lowercase letter."
for(i=0;i<4;i++)
printf("%c %s\n",s,isupper(s)? " is a uppercase letter.":" not a uppercase letter."
return 0;
}
上面这段小程式将对两个汉字(四个字符)进行测试——是否字母、是否大写、是否小写:
结果显示:
? is a letter.
? is a letter.
? is a letter.
? is a letter.
? is a lowercase letter.
? is a lowercase letter.
? not a lowercase letter.
? is a lowercase letter.
? is a uppercase letter.
? is a uppercase letter.
? is a uppercase letter.
? is a uppercase letter.
看见了吧,都是字母,且有几个既是大写又是小写!
这种逻辑关系让我大惑不解, 如果再使用 tolower() toupper()函数,则结果更加莫明其妙,
如果有ctype函数实现的原型就好了!
由于汉字超范围的原因:对于高低位的ASCII值都落在0x5b-0x5f、0x7b-0x7f区间的汉字不会发生变化,比例算很小的吧。
|
|
2004-7-19 00:00 |
|
|
willsort
元老会员
Batchinger
积分 4432
发帖 1512
注册 2002-10-18
状态 离线
|
『第
9 楼』:
Re bush: 这两天正在整理我以前发过的旧帖,偶然见到这个未结的话题,重新测试了一下,得出以下结论。 8楼程序的问题恰恰还是出在“char其低7位的值”上。我们知道,C标准未定义char型是否有符号,所以很多编译器的实现(包括TC2),都将char分为了signed char和unsigned char,如果定义时缺省符号修饰关键词,那么与int一样,它被默认为signed char。而上述程序中的char s[]="你好";则正是定义了有符号的字符数组。 此时,问题就很明白了,"你好"二字被拆为4个大于128的字符,分别存入数组s中,但是因为s是有符号的,不能大于128,所以他们被转为负值;而ctype的函数显然对此没有准备,因为其算法大概是通过查询一个长为128/256的整型数组来实现的,数组通过位运算保存了1-128/256每个字符所具有的类型,而查询的字符就是这个数组的下标索引值。那么显然,如果这个下标值为负,结果就成了未定义的,取真值也成了可能。而toupper和tolower也基于类似的原因出错了。 所以,解决它的办法很简单,只有将字符数组的定义前加一个unsigned即可,这也是大多数C编程者经常忽略的修饰符。 至于,你所说的原型,只要查看ctype.h即可得到,录于下方,从中可以很明显的看出其中的算法。
Quote: | #define _IS_SP 1 /* is space */
#define _IS_DIG 2 /* is digit indicator */
#define _IS_UPP 4 /* is upper case */
#define _IS_LOW 8 /* is lower case */
#define _IS_HEX 16 /* [A-F or [a-f] */
#define _IS_CTL 32 /* Control */
#define _IS_PUN 64 /* punctuation */extern char _Cdecl _ctype[]; /* Character type array */#define isalnum(c) (_ctype[(c) + 1] & (_IS_DIG | _IS_UPP | _IS_LOW))
#define isalpha(c) (_ctype[(c) + 1] & (_IS_UPP | _IS_LOW))
#define isascii(c) ((unsigned)(c) < 128)
#define iscntrl(c) (_ctype[(c) + 1] & _IS_CTL)
#define isdigit(c) (_ctype[(c) + 1] & _IS_DIG)
#define isgraph(c) ((c) >= 0x21 && (c) <= 0x7e)
#define islower(c) (_ctype[(c) + 1] & _IS_LOW)
#define isprint(c) ((c) >= 0x20 && (c) <= 0x7e)
#define ispunct(c) (_ctype[(c) + 1] & _IS_PUN)
#define isspace(c) (_ctype[(c) + 1] & _IS_SP)
#define isupper(c) (_ctype[(c) + 1] & _IS_UPP)
#define isxdigit(c) (_ctype[(c) + 1] & (_IS_DIG | _IS_HEX))#define _toupper(c) ((c) + 'A' - 'a')
#define _tolower(c) ((c) + 'a' - 'A')
#define toascii(c) ((c) & 0x7f)int _Cdecl tolower(int ch);
int _Cdecl toupper(int ch); |
|
|
※ Batchinger 致 Bat Fans:请访问 [讨论]批处理编程的异类 ,欢迎交流与共享批处理编程心得! |
|
2005-4-12 00:00 |
|