今天我写了一个简单的程序来加密我的.txt文件。我看到,我可以将char值设置为高于255
这是代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char** argv)
{
FILE* fp;
FILE* fp2;
char buffor = '\0';
int szyfr = 0;
if(argc < 4)
{
printf("Za malo argumentow (c/dc, sciezka, szyfr)!\n");
exit(0);
}
{
int i;
for(i = 0;i < strlen(argv[3]);++i)
{
szyfr *= 10;
szyfr += argv[3][i]-48;
}
}
if(!strncmp(argv[1], "c", 1))
{
fp = fopen(argv[2], "r");
fp2 = fopen("crypted.data", "w");
if(!fp)
{
printf("Cannot open file: %s!", argv[2]);
exit(0);
}
while(1)
{
buffor = fgetc(fp);
if(feof(fp) != 0) break;
fputc(buffor+szyfr, fp2);
}
fputc_unlocked(
fclose(fp);
fclose(fp2);
}
else if(!strncmp(argv[1], "dc", 2))
{
fp = fopen(argv[2], "r");
fp2 = fopen("uncrypted.txt", "w");
if(!fp)
{
printf("Cannot open file: %s!", argv[2]);
exit(0);
}
while(1)
{
buffor = fgetc(fp);
if(feof(fp) != 0) break;
fputc(buffor-szyfr, fp2);
}
fclose(fp);
fclose(fp2);
}
return 0;
}
无论你在szyfr值中设置什么,这都可行,但.data文件中的字符非常奇怪(例如对于666 szyfr,它将像“×ýû¤”) 为什么这不会给出关于char记忆的错误或类似的东西?
PS:对不起波兰代码中的一些文字,但我忘了这个
答案 0 :(得分:4)
我看到,我可以将char值设置为高于255。
我想你是在谈论fputc()
的第一个论点,也许是关于fgetc()
的返回值。这些都有int
类型,但这并不意味着您认为它意味着什么。两个函数的行为都是根据类型unsigned char
:
<强> fgetc()
强>:
fgetc
函数获取该字符作为转换为int的无符号字符 [...]
(C2011, 2.21.7.1/2;重点补充)
<强> fputc()
强>:
fputc
函数将c
指定的字符(转换为无符号字符)写入stream
指向的输出流[... ]
(C2011, 2.21.7.3/2;重点补充)
所以是的,因为类型int
的范围在实践中总是大于unsigned char
类型的范围,您可以传递大于unsigned char
可以表示的值{ {1}}。但不,这不会导致以可以回读的方式编写该值。转换为fputc()
将导致实际写入的字符在unsigned char
范围内,对于您来说几乎肯定是0 - 255.
为什么这不会给出关于char记忆的错误或类似的东西?
unsigned char
中没有错误,因为您提供的参数的行为已经完美定义。但是,即使出现错误,您的代码也不会告诉您,因为这样的错误会通过fputc()
的返回值传递给您的程序,您不会检查它。
关于广角字符I / O
请注意,fputc()
和fgetwc()
等宽字符I / O函数以较大的单位运行,但它们的基本行为并没有根本的不同。它涉及类似于fputwc()
和fgetc()
执行的转换 - 因此提供了相同的数据损坏可能性 - 您可能仍会在加密文件中看到奇怪的字符,尽管可能是不同的字符。
关于奇怪的字符
就加密文件中出现的奇怪字符而言,这几乎是预料之中的,虽然在某种程度上取决于您的编辑器或终端(取决于您显示文件的方式)假设文件的字符编码。您的加密方案有效地将字符数据转换为二进制数据,因此期望它看起来像字符数据是不合理的。
答案 1 :(得分:2)
C是一种低级语言,可以完成您所说的内容,没有任何帮助或参数。
您将变量buffor
声明为char
,然后调用返回fgetc()
的函数int
,然后分配它。 C说&#34;好。你曾经让我把16加仑的水倒进一个8加仑的水桶里,所以我做了。&#34;现在你已经拥有了一个完整的8加仑水桶和一个湿地板。 C只是砍掉8位并丢弃它们,所以例如,你永远无法判断fgetc()
何时返回EOF,因为它的值大于8位。
如果您想确保8位变量只能获得8位值,那么在分配它们之前,您必须自己检查它们。