本文写于 2016年11月25日,距今已超过 1 年,距 2020年07月25日 的最后一次修改也已超过 3 个月,部分内容可能已经过时,您可以按需阅读。如果图片无法显示或者下载链接失效,请给我反馈,谢谢!


0 0 投票数
评分

转载

原文标题:《20161116 – 一次DEBUG的小结》

原文链接:http://www.starrylyc.com/wordpress/?p=77

原文作者:Summerfirefly

转载授权:

sp161125_010012


//本程序目的为去除一段文字开头和每行末尾的 Whitespace
//以及单词之间多余的 whitespace,仅保留第一个 whitespace
//ECNU OJ Problem 3167
#include <stdio.h>
int main()
{
    int i,n;
    char a[1000],x;
    i=0;
    scanf("%c",&x);
    for (;x==' '||x=='\t'||x=='\n';)
        scanf ("%c",&x);
    a[i]=x;
    i++;
    while (scanf("%c",&x)!=EOF)
    {
        if ((x==' '||x=='\t'||x=='\n')&&a[i-1]!=' '&&a[i-1]!='\t'&&a[i-1]!='\n')
        {
            a[i]=x;
            i++;
        }
        if(x!=' '&&x!='\t'&&x!='\n')
        {
            a[i]=x;
            i++;
        }
    }
    if(a[i-1]==' '||a[i-1]=='\t'||a[i-1]=='\n')
    {
        i=i-1;
        a[i]='\0';
    }
    else
        a[i]='\0';
    for (n=0;n<i;n++)
        printf ("%c",a[n]);
    return 0;
}

以上为一位同学于 20161116 晚发来的一段代码,EOJ 测试 Wrong Answer,本地测试通过(注:这里的本地测试就是本次总结的重点之一)无法理解便交给我,整体 debug 用时一个多小时(注:总结重点之二,debug 的方式要注意)

拿到代码后第一步在 Code::Blocks下进行 debug 测试,用单行数据进行测试,完全无误(事后证明确实无误),用文件重定向在终端模拟OJ的文件测试多行数据,无误,但事后证明这里的测试出现严重的失误,对于可能的输入方式没有考虑完全,导致浪费大量时间

经过长时间的不全面的测试数据进行测试后想到存在如下情况:

Input:

\t\taaaaa     aaa\t      \t\n

aa        a\n

EOF

即多行数据,且非末行的末尾换行符之前连接一串 whitespace,上述错误的代码输出结果为

Output:

aaaaa aaa\taa a\n

显然不正确,本应输出两行,最终只有一行,问题出在Line 19的判断条件上,由于本算法是一次性处理整个文件,而又没有考虑到连续多个空白字符之后紧跟换行符的情况,导致 \t\t\n 这类型序列只存入了 \t 而丢弃了 \n,导致行的缺失,debug 时同样没有注意到这一点,白白浪费大量时间

总结:

  1. 本地测试时一定要将所有输入的可能性考虑完全
  2. 考虑可能的输入时一定要结合自己的算法的特点,如本例,由于我自己写的算法是逐行处理,将整个文件作为类似二维的处理,所有换行符都在一行的末尾,因此不存在丢失应有的换行符的问题,但上述代码为整体处理,类似在一维上处理多行文本,换行符不一定在数组末尾。如果仍然按照单行处理的思路,即两个单词之间的 whitespace 只保留第一个,来一次性处理多行文本,就会有丢失换行符的可能性。

Debug 是一项非常重要的技能!非常重要!同时 Debug 的时候一定要注意方法和以前的经验教训,否则将会浪费大量时间。

全面的测试数据将为程序的调试节省大量时间

2016-11-17 Summerfirefly

0 0 投票数
评分
2条留言
订阅评论
提醒
guest

在点击发表评论按钮时,网络请求的数据包含浏览器版本、操作系统版本和 IP 地址;您的网络服务提供商、雇主或学校、政府机构可能会看到您的访问活动;根据浏览器默认行为、操作系统设置和安全防护软件的设置不同,您的浏览器可能会也可能不会在本地 Cookies 缓存您输入的用户名、邮箱以便下次评论使用。

请对自己的言行负责。

您想以什么身份发表评论
邮箱将在您的评论被回复时给您通知
(可选)如果您也有个人网站,不妨分享一下
我对这篇文章的评分
这篇文章给您带来多大帮助
2 评论
内联反馈
查看所有评论
sscjwdyzdw
sscjwdyzdw(@sscjwdyzdw)
2016年12月8日 15:21

这题难主要是因为末尾就算有whitespace输出也看不到,所以不如假定n t ‘ ‘是实在的abc,然后输出会比较容易的看出程序问题