我已编写代码来执行Caesar Shift Cipher,从一个名为“input.txt”的文件中获取输入,并将输出写入名为“output.txt”的文件。技术上工作正常;输出几乎完美,但是当我运行它时,我得到一条关于Debug Assertion Failed
的{{1}}消息,这是关闭输出文件的行。该错误还表示:表达式:Line 56
。这是我的代码:
(unsigned)(c+1) <= 256
哦,还有一个不太紧迫的问题,但是当代码吐出输入时,如果输入改变了行,比如“输入文本\ n这里”,那么当它为“text”和“here”设置密码时,把它们放在一起,而不是把它们放在像它应该的那样单独的线上。如果有人知道为什么那样可以帮助我,我会很感激,但最重要的是错误。
答案 0 :(得分:0)
这里有两个问题。
char c, /* ... */;
for(i=0;(c=getc(file1))!=EOF && i<MAX;i++)
input[i]=c;
这是错误的。 getc
会返回int
,因此c也应为int
。原因是getc
有两种类型的返回值:
如果您直接转换为char
,则无法检查错误。 char
可能已签名或未签名。如果它是未签名的,那么(c=getc(file1))
将最终成为正数,这不能比较等于EOF
。因此,遇到EOF
时,您的循环不会结束。如果您的char
已签名,那么您的程序可能会以其他奇怪的方式出现故障,例如过早地终止 ,或者在某些计算机上进行分段。
这适用于所有标准C功能!确保在转换之前检查返回值!包括scanf
。
<ctype.h>
是您获取isalpha
和toupper
函数的地方。
7.4角色处理
1标题声明了几个有用的函数 分类和映射字符.198)在所有情况下,参数都是 int ,其值应表示为 unsigned char 或者等于宏EOF的值。如果参数有任何 其他值,行为未定义。
在我看来,您可能正在通过将可能的负值传递到isupper
来调用未定义的行为。
答案 1 :(得分:0)
如果您使用的是MSVC,请注意调试CRT会检查传递给isalpha的参数是否在EOF
或0..0xff
范围内(请参阅MSDN)。在您的代码中,您调用的isalpha(input[i])
input
为char
数组。由于isalpha
需要int
,因此您最终可能会使用超出允许范围的值调用isalpha
。您应该将来电更改为isalpha((unsigned char)input[i])
。
我还会相应地将呼叫更改为toupper
。
正如undefined behaviour
已经说过,您必须将getc
的结果存储在int
变量中,将其与EOF
进行比较,然后将其转换为char
并存储它。将其转换为char
后,您无法将其与EOF
进行比较(EOF
是一个int
值,不能表示为char
)。