凯撒密码;调试断言失败

时间:2013-04-24 04:22:24

标签: c

我已编写代码来执行Caesar Shift Cipher,从一个名为“input.txt”的文件中获取输入,并将输出写入名为“output.txt”的文件。技术上工作正常;输出几乎完美,但是当我运行它时,我得到一条关于Debug Assertion Failed的{​​{1}}消息,这是关闭输出文件的行。该错误还表示:表达式:Line 56。这是我的代码:

(unsigned)(c+1) <= 256

哦,还有一个不太紧迫的问题,但是当代码吐出输入时,如果输入改变了行,比如“输入文本\ n这里”,那么当它为“text”和“here”设置密码时,把它们放在一起,而不是把它们放在像它应该的那样单独的线上。如果有人知道为什么那样可以帮助我,我会很感激,但最重要的是错误。

2 个答案:

答案 0 :(得分:0)

这里有两个问题。

char c, /* ... */;
for(i=0;(c=getc(file1))!=EOF && i<MAX;i++)
    input[i]=c;

这是错误的。 getc会返回int,因此c也应为int。原因是getc有两种类型的返回值:

  1. 正值,可以表示为 unsigned char
  2. 负值,表示错误。
  3. 如果您直接转换为char,则无法检查错误。 char可能已签名或未签名。如果它是未签名的,那么(c=getc(file1))将最终成为正数,这不能比较等于EOF。因此,遇到EOF时,您的循环不会结束。如果您的char已签名,那么您的程序可能会以其他奇怪的方式出现故障,例如过早地终止 ,或者在某些计算机上进行分段。

    这适用于所有标准C功能!确保在转换之前检查返回值!包括scanf

    <ctype.h>是您获取isalphatoupper函数的地方。

      

    7.4角色处理

         

    1标题声明了几个有用的函数   分类和映射字符.198)在所有情况下,参数都是    int ,其值应表示为 unsigned char   或者等于宏EOF的值。如果参数有任何   其他值,行为未定义。

    在我看来,您可能正在通过将可能的负值传递到isupper来调用未定义的行为。

答案 1 :(得分:0)

如果您使用的是MSVC,请注意调试CRT会检查传递给isalpha的参数是否在EOF0..0xff范围内(请参阅MSDN)。在您的代码中,您调用的isalpha(input[i]) inputchar数组。由于isalpha需要int,因此您最终可能会使用超出允许范围的值调用isalpha。您应该将来电更改为isalpha((unsigned char)input[i])

我还会相应地将呼叫更改为toupper

正如undefined behaviour已经说过,您必须将getc的结果存储在int变量中,将其与EOF进行比较,然后将其转换为char并存储它。将其转换为char后,您无法将其与EOF进行比较(EOF是一个int值,不能表示为char)。