0

我编写了代码来执行凯撒移位密码,从名为“input.txt”的文件中获取输入并将输出写入名为“output.txt”的文件中。它在技术上运行良好;输出几乎完美,但是当我运行它时,我收到一条Debug Assertion Failed消息,说明Line 56哪一行是关闭输出文件的行。错误还说:表达式:(unsigned)(c+1) <= 256。这是我的代码:

void cipher(char input[], int key);

int main()
{

    int i, key=0;
    char c, input[MAX];
    FILE *file1;
    file1 = fopen("input.txt","r");

    printf("Enter the key: ");
    scanf("%d", &key);
    getchar();

    for(i=0;(c=getc(file1))!=EOF && i<MAX;i++)
        input[i]=c;
    fclose(file1);
    cipher(input, key);
    return 0;
}

void cipher(char input[], int key)
{
    int length = strlen(input)-1;
    int i;
    char c;
    FILE *file2;
    file2 = fopen("output.txt","w");
    for (i=0;i<length;i++)
    {
        if (isalpha(input[i]))
        {
            c = (toupper(input[i]) - 'A'+key) % 26 + 'A';
            fprintf(file2, "%c", c);
        }
        else if (input[i]==' ')
            fprintf(file2, "\n");
    }

    fclose(file2);
}

哦,还有一个不那么紧迫的问题,但是当代码吐出输入时,如果输入改变行,比如“输入文本\n 这里”,那么当它对“文本”和“这里”进行密码时,它会将它们放在一起而不是像应该的那样将它们放在单独的行上。如果有人知道这是为什么并且可以帮助我,我将不胜感激,但主要是那个错误。

4

2 回答 2

0

这里有两个问题。

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

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

  1. 一个正值,可以表示为unsigned char
  2. 负值,表示错误。

如果直接转换为char,则无法检查错误。char可能已签名或未签名。如果它是无符号的,那么(c=getc(file1))最终将是一个正数,不可能比较等于EOF. 因此,您的循环不会在EOF遇到时结束。如果您char已签名,那么您的程序可能会以其他奇怪的方式出现故障,例如过早终止循环,或在某些机器上出现段错误。

这适用于所有标准 C 函数!确保在转换它们之前检查返回值!这包括scanf.

<ctype.h>是您从中获取isalphatoupper功能的地方。

7.4 字符处理

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

在我看来,您可能会通过将可能的负值传递给isupper.

于 2013-04-24T05:49:23.187 回答
0

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

我也会toupper相应地更改调用。

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

于 2013-04-24T09:53:26.320 回答