在 C 中使用 fwrite 的错误 int 值
Wrong int values using fwrite in C
我正在尝试用 C 语言为简单的 UDP 客户端-服务器应用程序创建密钥管理器。我 运行 遇到了将密钥写入文本文件的问题。我目前正在将结构存储到一个 txt 文件中,但是当我使用 int 时,我的输出是相同的。
// ...
// if the principal is requesting to registering, store it in a file
if (req.request_type == regista) {
printf("Writing key to file...\n");
pFile = fopen("crypt.txt", "ab");
fwrite(&req, sizeof(struct P2Key), 1, pFile);
printf("Written: %u %i ", req.principal_id, req.public_key);
fclose(pFile);
printf("Done\n");
}
// if pincipal is requesting key
if (req.request_type == request_key) {
pFile = fopen("crypt.txt", "rb");
printf("Key requested for: %u %i ", req.principal_id, req.public_key);
printf("Searching for Requested Key\n");
while (fread(&res, sizeof(struct P2Key), 1, pFile) == 1) {
printf("Read: %u %i\n", res.principal_id, res.public_key);
printf("Line Number: %ld\n", ftell(pFile));
// if this is the client requested, send the key
if (req.principal_id == res.principal_id) {
send_key.principal_id = req.principal_id;
send_key.public_key = req.public_key;
printf("Sending Key...\n");
// ...
}
这是写入文件的结构
typedef struct P2Key {
enum {
regista, request_key
} request_type; /* same size as an unsigned int */
unsigned int principal_id; /* client or server identifier */
int public_key; /* public key */
} P2Key;
我尝试读取文件时得到的输出:
Writing key to file...
Written: 2 7 Done
...
Writing key to file...
Written: 1 7 Done
Key requested for: 2 7 Searching for Requested Key
Read: 512 1792
Line Number: 12
Read: 256 1792
Line Number: 24
End of file reached.
我已经在这里工作了几个小时,感谢您的帮助。
您正在以附加模式写入;自从您切换到编写结构后,您是否重新创建了文件?您不显示甚至测试写入的字节数,因此您不知道写入是否成功。
我的第一个怀疑是您一直在追加此文件,并且它的开头附近有旧数据,与您的结构不符。我建议先清空文件。在 UNIX/Linux 上,您可以使用 shell 中的“> crypt.txt”来执行此操作。
现在开始调试代码。捕获所有读取和写入的 return 值,它们 return size_t,因此您至少可以在调试器中查看 return 值。如果您没有写入预期的字节数——结构的大小,您可能想要记录错误等。在调试器中跳过写入并关闭,然后使用十六进制转储或类似实用程序查看文件。文件中的值是否符合您的预期?文件包含的字节数是否与结构的大小相同?
然后继续阅读代码。观察代码使用 fread 从文件加载每个值。观察您从 fread 获得的 return 值——它是您的结构的大小吗?读取完成后查看结构中的值。它看起来像是在读你写的东西吗?
您需要检查您的文件,似乎由于某种原因其中可能有一个(或多个)额外的字节,这导致您以错误的偏移量读取结构。
我基于以下几点:
- 您只需将结构附加到现有文件,而不管文件中当前有多少字节;和
- 您正在阅读的值是
256
的精确倍数。更重要的是,它们是 256
乘以 1
、2
和 7
(256
、512
和 1792
)。
一种简单的检查方法是简单地删除文件(或清空它)并再次 运行 您的程序。如果您没有任何其他内容写入该文件,它应该可以正常工作。
如果您愿意,实际上有很多方法可以解决此类问题。其中包括:
- 打开时检查文件大小是否为结构大小的倍数。
- 在您的结构中添加一个(或多个)指示符字段以检查每个项目,例如开头的字段称为
check_dead
和末尾的另一个字段称为 check_beef
,您始终 设置为 0xdead
和 0xbeef
写入记录,始终 读取记录时检查。
您的程序似乎可以在此处运行。请注意,我使用的是 linux,但由于您在 fopen
参数中使用了 b
,即使您使用的是 WinX,它也应该是相同的。
我必须合成一些缺失的元素才能获得完整的程序。我从 main
传下来 req
,所以 [new] action
函数必须使用 req->*
而不是 req.*
,但是,否则它应该是相同的作为您的代码:
#include <stdio.h>
typedef struct P2Key {
enum {
regista, request_key
} request_type; /* same size as an unsigned int */
unsigned int principal_id; /* client or server identifier */
int public_key; /* public key */
} P2Key;
void
action(P2Key *req)
{
FILE *pFile;
P2Key res;
P2Key send_key;
printf("request_type=%d regista=%d request_key=%d\n",
req->request_type,regista,request_key);
// ...
// if the principal is requesting to registering, store it in a file
if (req->request_type == regista) {
printf("Writing key to file...\n");
pFile = fopen("crypt.txt", "ab");
fwrite(req, sizeof(struct P2Key), 1, pFile);
printf("Written: %u %i ", req->principal_id, req->public_key);
fclose(pFile);
printf("Done\n");
}
// if pincipal is requesting key
if (req->request_type == request_key) {
pFile = fopen("crypt.txt", "rb");
printf("Key requested for: %u %i ", req->principal_id, req->public_key);
printf("Searching for Requested Key\n");
while (fread(&res, sizeof(struct P2Key), 1, pFile) == 1) {
printf("Read: %u %i\n", res.principal_id, res.public_key);
printf("Line Number: %ld\n", ftell(pFile));
// if this is the client requested, send the key
if (req->principal_id == res.principal_id) {
send_key.principal_id = req->principal_id;
send_key.public_key = req->public_key;
printf("Sending Key...\n");
// ...
}
}
fclose(pFile);
}
}
int
main(void)
{
P2Key req;
while (1) {
printf("Cmd (regista=%d request_key=%d): ",regista,request_key);
fflush(stdout);
scanf("%d",&req.request_type);
scanf("%u %d",&req.principal_id,&req.public_key);
action(&req);
}
}
这是我得到的输出:
Cmd (regista=0 request_key=1): 0 5 6
request_type=0 regista=0 request_key=1
Writing key to file...
Written: 5 6 Done
Cmd (regista=0 request_key=1): 0 8 9
request_type=0 regista=0 request_key=1
Writing key to file...
Written: 8 9 Done
Cmd (regista=0 request_key=1): 1 8 9
request_type=1 regista=0 request_key=1
Key requested for: 8 9 Searching for Requested Key
Read: 1 2
Line Number: 12
Read: 5 6
Line Number: 24
Read: 8 9
Line Number: 36
Sending Key...
Cmd (regista=0 request_key=1): ^C
我正在尝试用 C 语言为简单的 UDP 客户端-服务器应用程序创建密钥管理器。我 运行 遇到了将密钥写入文本文件的问题。我目前正在将结构存储到一个 txt 文件中,但是当我使用 int 时,我的输出是相同的。
// ...
// if the principal is requesting to registering, store it in a file
if (req.request_type == regista) {
printf("Writing key to file...\n");
pFile = fopen("crypt.txt", "ab");
fwrite(&req, sizeof(struct P2Key), 1, pFile);
printf("Written: %u %i ", req.principal_id, req.public_key);
fclose(pFile);
printf("Done\n");
}
// if pincipal is requesting key
if (req.request_type == request_key) {
pFile = fopen("crypt.txt", "rb");
printf("Key requested for: %u %i ", req.principal_id, req.public_key);
printf("Searching for Requested Key\n");
while (fread(&res, sizeof(struct P2Key), 1, pFile) == 1) {
printf("Read: %u %i\n", res.principal_id, res.public_key);
printf("Line Number: %ld\n", ftell(pFile));
// if this is the client requested, send the key
if (req.principal_id == res.principal_id) {
send_key.principal_id = req.principal_id;
send_key.public_key = req.public_key;
printf("Sending Key...\n");
// ...
}
这是写入文件的结构
typedef struct P2Key {
enum {
regista, request_key
} request_type; /* same size as an unsigned int */
unsigned int principal_id; /* client or server identifier */
int public_key; /* public key */
} P2Key;
我尝试读取文件时得到的输出:
Writing key to file...
Written: 2 7 Done
...
Writing key to file...
Written: 1 7 Done
Key requested for: 2 7 Searching for Requested Key
Read: 512 1792
Line Number: 12
Read: 256 1792
Line Number: 24
End of file reached.
我已经在这里工作了几个小时,感谢您的帮助。
您正在以附加模式写入;自从您切换到编写结构后,您是否重新创建了文件?您不显示甚至测试写入的字节数,因此您不知道写入是否成功。
我的第一个怀疑是您一直在追加此文件,并且它的开头附近有旧数据,与您的结构不符。我建议先清空文件。在 UNIX/Linux 上,您可以使用 shell 中的“> crypt.txt”来执行此操作。
现在开始调试代码。捕获所有读取和写入的 return 值,它们 return size_t,因此您至少可以在调试器中查看 return 值。如果您没有写入预期的字节数——结构的大小,您可能想要记录错误等。在调试器中跳过写入并关闭,然后使用十六进制转储或类似实用程序查看文件。文件中的值是否符合您的预期?文件包含的字节数是否与结构的大小相同?
然后继续阅读代码。观察代码使用 fread 从文件加载每个值。观察您从 fread 获得的 return 值——它是您的结构的大小吗?读取完成后查看结构中的值。它看起来像是在读你写的东西吗?
您需要检查您的文件,似乎由于某种原因其中可能有一个(或多个)额外的字节,这导致您以错误的偏移量读取结构。
我基于以下几点:
- 您只需将结构附加到现有文件,而不管文件中当前有多少字节;和
- 您正在阅读的值是
256
的精确倍数。更重要的是,它们是256
乘以1
、2
和7
(256
、512
和1792
)。
一种简单的检查方法是简单地删除文件(或清空它)并再次 运行 您的程序。如果您没有任何其他内容写入该文件,它应该可以正常工作。
如果您愿意,实际上有很多方法可以解决此类问题。其中包括:
- 打开时检查文件大小是否为结构大小的倍数。
- 在您的结构中添加一个(或多个)指示符字段以检查每个项目,例如开头的字段称为
check_dead
和末尾的另一个字段称为check_beef
,您始终 设置为0xdead
和0xbeef
写入记录,始终 读取记录时检查。
您的程序似乎可以在此处运行。请注意,我使用的是 linux,但由于您在 fopen
参数中使用了 b
,即使您使用的是 WinX,它也应该是相同的。
我必须合成一些缺失的元素才能获得完整的程序。我从 main
传下来 req
,所以 [new] action
函数必须使用 req->*
而不是 req.*
,但是,否则它应该是相同的作为您的代码:
#include <stdio.h>
typedef struct P2Key {
enum {
regista, request_key
} request_type; /* same size as an unsigned int */
unsigned int principal_id; /* client or server identifier */
int public_key; /* public key */
} P2Key;
void
action(P2Key *req)
{
FILE *pFile;
P2Key res;
P2Key send_key;
printf("request_type=%d regista=%d request_key=%d\n",
req->request_type,regista,request_key);
// ...
// if the principal is requesting to registering, store it in a file
if (req->request_type == regista) {
printf("Writing key to file...\n");
pFile = fopen("crypt.txt", "ab");
fwrite(req, sizeof(struct P2Key), 1, pFile);
printf("Written: %u %i ", req->principal_id, req->public_key);
fclose(pFile);
printf("Done\n");
}
// if pincipal is requesting key
if (req->request_type == request_key) {
pFile = fopen("crypt.txt", "rb");
printf("Key requested for: %u %i ", req->principal_id, req->public_key);
printf("Searching for Requested Key\n");
while (fread(&res, sizeof(struct P2Key), 1, pFile) == 1) {
printf("Read: %u %i\n", res.principal_id, res.public_key);
printf("Line Number: %ld\n", ftell(pFile));
// if this is the client requested, send the key
if (req->principal_id == res.principal_id) {
send_key.principal_id = req->principal_id;
send_key.public_key = req->public_key;
printf("Sending Key...\n");
// ...
}
}
fclose(pFile);
}
}
int
main(void)
{
P2Key req;
while (1) {
printf("Cmd (regista=%d request_key=%d): ",regista,request_key);
fflush(stdout);
scanf("%d",&req.request_type);
scanf("%u %d",&req.principal_id,&req.public_key);
action(&req);
}
}
这是我得到的输出:
Cmd (regista=0 request_key=1): 0 5 6
request_type=0 regista=0 request_key=1
Writing key to file...
Written: 5 6 Done
Cmd (regista=0 request_key=1): 0 8 9
request_type=0 regista=0 request_key=1
Writing key to file...
Written: 8 9 Done
Cmd (regista=0 request_key=1): 1 8 9
request_type=1 regista=0 request_key=1
Key requested for: 8 9 Searching for Requested Key
Read: 1 2
Line Number: 12
Read: 5 6
Line Number: 24
Read: 8 9
Line Number: 36
Sending Key...
Cmd (regista=0 request_key=1): ^C