V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
shilyx
V2EX  ›  程序员

[c 语言谜题 第二题] 程序改动,求输出数字

  •  
  •   shilyx · 2018-09-27 18:33:33 +08:00 · 2629 次点击
    这是一个创建于 2009 天前的主题,其中的信息可能已经有所发展或是发生改变。

    昨天出了一道题[c 语言谜题] 程序填空,老程序员来做做,不少朋友都搞定了,今天是第二题

    #include <stdio.h>
    
    struct FileData {
        FILE *fp;
        size_t size;
        unsigned char buf[1024];
    };
    
    main() {
        struct FileData fileData;
        unsigned char res = 0;
        size_t i;
    
        fileData.fp = fopen(__FILE__, "rb");
        fileData.size = fread(fileData.buf, 1, sizeof(fileData.buf), fileData.fp);
    
        for (i = 0; i < fileData.size; ++i) {
            if (fileData.buf[i] != ' ' && fileData.buf[i] != '\t' && fileData.buf[i] != '\r' && fileData.buf[i] != '\n') {
                res += fileData.buf[i];
            }
        }
    
        fclose(fileData.fp);
        printf("%u\n", (unsigned)res);
    }
    

    此程序是c 程序,文件扩展名“.c ”,意在将自身源代码中的所有“有效字符”相加后输出结果,虽然相加发生了溢出,但对于确定的输入,会有确定的输出。

    此程序运行后输出的数字是220,可以先验证一下。

    要求,替换掉源代码中的一个字符,条件如下:

    • 1、替换一个字符即去掉一个字符,再在相同位置添加一个字符。替换掉的字符和添加的字符不能相同
    • 2、仅限一个字符,字符大小一个字节
    • 3、程序可以编译运行(忽略编译和链接的警告),无运行时异常或崩溃
    • 4、被替换掉的字符不可以是数字
    • 5、被替换掉的字符不可以是引号内的(单引号或双引号)
    • 6、被替换掉的字符和添加的字符都必须是可打印字符、可见、不是空白字符、换行符等
    • 7、不影响程序意图(累加“有效字符”输出数字结果)
    • 8、同时兼容 gcc 和 vs ( 2008 以上即可)

    问:经过了你的合法的替换,程序运行后的输出数字是几呢?

    ps:角度比较刁钻,切勿因此虐心,仅供一乐,不承担法律责任

    第 1 条附言  ·  2018-09-27 19:41:58 +08:00
    发现一个大漏洞,把分号换逗号,可以换的地方太多了。

    因此,我做出一个补充,逗号不算,不能将字符替换成逗号。

    没考虑周全,sorry。

    截至词条 append,还没有出现这个答案( 205 )
    27 条回复    2018-10-12 08:35:02 +08:00
    pkokp8
        1
    pkokp8  
       2018-09-27 18:53:44 +08:00 via Android
    第一感觉,18 行入手
    shilyx
        2
    shilyx  
    OP
       2018-09-27 18:57:46 +08:00
    @pkokp8 试试吧,不过和我预设的答案不一致

    有多个答案也不一定
    pkokp8
        3
    pkokp8  
       2018-09-27 18:58:54 +08:00 via Android
    @pkokp8 源程序功能完全不变,改 if 判断最后一个!为>,输出当然不变。这算取巧了吧
    pkokp8
        4
    pkokp8  
       2018-09-27 19:01:43 +08:00 via Android
    @pkokp8 忘了源代码的一起了,193
    pkokp8
        5
    pkokp8  
       2018-09-27 19:05:19 +08:00 via Android
    @pkokp8 脑抽了,能不能删帖。。。。
    刚吃完饭回到电脑前试了下不对
    GeruzoniAnsasu
        6
    GeruzoniAnsasu  
       2018-09-27 19:08:25 +08:00
    unsigned char 作为和 哈哈哈哈


    我的结果是 19
    GeruzoniAnsasu
        7
    GeruzoniAnsasu  
       2018-09-27 19:09:37 +08:00
    @GeruzoniAnsasu 啊,测错了 丢人
    whoami9894
        8
    whoami9894  
       2018-09-27 19:12:40 +08:00 via Android
    112
    不过好像改变意图了
    GeruzoniAnsasu
        9
    GeruzoniAnsasu  
       2018-09-27 19:21:53 +08:00
    emmmmmm 219 221 203 我只有 gcc
    innoink
        10
    innoink  
       2018-09-27 19:41:52 +08:00 via Android
    倒数第三行
    innoink
        11
    innoink  
       2018-09-27 19:48:11 +08:00 via Android
    205
    innoink
        12
    innoink  
       2018-09-27 19:48:28 +08:00 via Android
    。。。
    casparchen
        13
    casparchen  
       2018-09-27 20:05:21 +08:00
    for (i = 0; i < fileData.size; ++i)
    这句,把小于符号完成异或^
    casparchen
        14
    casparchen  
       2018-09-27 20:05:39 +08:00
    结果 254
    casparchen
        15
    casparchen  
       2018-09-27 20:08:14 +08:00
    异或的话,只有 i= fileData.size 才是 false 然后退出循环。不影响结果
    innoink
        16
    innoink  
       2018-09-27 20:13:02 +08:00
    那就是改 for 那一行 254
    建议附上一个在线编译器比如 https://tool.lu/coderunner 方便手机用户
    codepad 一直打不开
    casparchen
        17
    casparchen  
       2018-09-27 20:20:57 +08:00
    @casparchen #13 好吧,换成减号也是可以的,结果 205
    casparchen
        18
    casparchen  
       2018-09-27 20:30:05 +08:00
    第二种换法,if (fileData.buf[i] != ' ' && fileData.buf[i] != '\t' && fileData.buf[i] != '\r' && fileData.buf[i] != '\n')
    这句任意&&换成&+也不影响结果。
    1 && 1 -> 1
    1 &+ 1 -> 1
    1 && 0 -> 0
    1 &+ 0 -> 0
    0 && 0 -> 0
    0 &+ 0 -> 0
    Ediacaran
        19
    Ediacaran  
       2018-09-27 20:48:19 +08:00
    < 改成 - 就是 205 了
    garzon
        20
    garzon  
       2018-09-27 21:45:40 +08:00
    感觉这题漏洞挺多的...上面已经有了正解 205,我来给个非预期解 222:
    size_t i; 改成 size_t i=
    garzon
        21
    garzon  
       2018-09-27 21:49:24 +08:00
    另:源程序在 msvc2017 不加#define _CRT_SECURE_NO_WARNINGS 是无法编译通过的,233
    garzon
        22
    garzon  
       2018-09-27 21:53:30 +08:00
    @casparchen 同理换成&-也行
    garzon
        23
    garzon  
       2018-09-27 21:58:34 +08:00
    试了下&&换&-,除了最后一个&&换成&-不行,其他都可以
    garzon
        24
    garzon  
       2018-09-27 22:04:02 +08:00
    @garzon 不对,傻了。换成&-程序意图改变了
    hmzt
        25
    hmzt  
       2018-09-28 10:41:46 +08:00
    我有个更刁钻的角度,你这段代码好像没有\t
    bfdh
        26
    bfdh  
       2018-09-28 17:41:54 +08:00
    没实测,貌似把下面这个数组任意改大小都行吧?
    unsigned char buf[1024];
    w01230
        27
    w01230  
       2018-10-12 08:35:02 +08:00
    貌似在 for 这部分动比较容易一些。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2981 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 36ms · UTC 15:05 · PVG 23:05 · LAX 08:05 · JFK 11:05
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.