免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 10663 | 回复: 6
打印 上一主题 下一主题

小写字母转换为大写字母 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-10-13 10:21 |只看该作者 |倒序浏览
一个很简单的小写字母转换为大写字母程序,但是转换前和转换后没有变化。
请问这样写错在哪里?谢谢。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int upperStr(char *to, char *from)
{
    if(from == NULL)
        return -1;
    while(*to++ = *from++)
    {
        if(*to >= 'a' && *to <= 'z')
            *to= *to - 32;
    }
    *to = '\0';
    return 0;
}

int main()
{
    char newStr[30], *oldStr ="abcd 1235 ADCD";
    memset(newStr, '\0', 30);
    printf("before upper the string is: %s\n", oldStr);
    if(upperStr(newStr,oldStr) == 0)
        printf("after upper the string is: %s\n", newStr);
    else
        printf("nothing has done\n");
    exit(0);
}

论坛徽章:
0
2 [报告]
发表于 2008-10-13 10:34 |只看该作者
to++得早了。应该先转换再++

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
3 [报告]
发表于 2008-10-13 10:38 |只看该作者
原帖由 熏红猴 于 2008-10-13 10:34 发表
to++得早了。应该先转换再++


正解。等到对t当前指向的字符处理完毕之后,再++,不然就处理成下一个字符的转换了

论坛徽章:
0
4 [报告]
发表于 2008-10-13 15:17 |只看该作者

回复 #2 熏红猴 的帖子

确实,断点一下,++提前了。

可是当年K&R为什么可以通过呢?
------------------------------------------------------
void strcpy(char *s, char *t)
{
    while((*s++ = *t++) != '\0')
     ;
}
在该版本中,s和t的自增运算放到了循环的测试部分中。表达式*t++的值是执行自增运算之前t所指向的字符。后缀运算符++表示在读取该字符之后才改变t的值。同样的道理,在s执行自增运算之前,字符就被存储到了指针s指向的旧位置。该字符值同时也用来和空字符'\0'进行比较运算,以控制循环的执行。最后的结果是依次将t指向的字符复制到s指向的位置,直到遇到结束符'\0'为止(同时也复制该结束符)。
为了进一步精炼程序,我们注意到,表达式同'\0'的比较是多余的,因为只需要判断表达式的值是否为0即可。因此可以进一步写成下列形式
void strcpy(char *s, char *t)
{
    while((*s++ = *t++))
     ;
}
----------------------------------------------------------------

Breakpoint 1, upperStr (to=0xbff35dde "", from=0x80485e0 "abcd 1235 ADCD")
    at upper.c:6
6       {
(gdb) p to
$3 = 0xbff35dde ""
(gdb) p from
$4 = 0x80485e0 "abcd 1235 ADCD"
(gdb) n
7               if(from == NULL)
(gdb) n
9               while(*to++ = *from++)
(gdb) n
11                      if(*to >= 'a' && *to <= 'z')
(gdb) p from
$5 = 0x80485e1 "bcd 1235 ADCD"
(gdb) p *(to-1)
$6 = 97 'a'
(gdb) p *to
$7 = 0 '\0'

论坛徽章:
0
5 [报告]
发表于 2008-10-13 15:28 |只看该作者

回复 #4 motive 的帖子

你看下人家的循环体是空,而你的还要判断*to啊。。

论坛徽章:
0
6 [报告]
发表于 2008-10-13 18:23 |只看该作者

回复 #5 雨过白鹭洲 的帖子

点醒了!
晕了。。。

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
7 [报告]
发表于 2008-10-13 19:29 |只看该作者
原帖由 motive 于 2008-10-13 15:17 发表
确实,断点一下,++提前了。

可是当年K&R为什么可以通过呢?
------------------------------------------------------
void strcpy(char *s, char *t)
{
    while((*s++ = *t++) != '\0')
     ;
}
...


人家里面没有对当前的这个字符操作,所以可以。你的里面还要进行转换,所以转换的时候一定要保证是你赋值时的那个字符,而不是下一个
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP