【问题标题】:Need help about binary files需要有关二进制文件的帮助
【发布时间】:2018-04-30 18:37:38
【问题描述】:

我在创建一个创建包含多行的 bin 文件的代码时遇到问题,每行包含每行 6 个值。例如: 我正在做一个小项目,其中每一行都是一个“密码”,所以我的系统将加载这个文件并从中读取所有密码,当它被更新等等。 我还没有实现读取文件的方法,因为我正在努力操作文件。 该项目将在 linux 上运行,具有 Raspberry pi 的 GPIO 功能 所以我使用 Visual Studio 来创建主要代码。

我当前的代码是:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char keys[4] = { '1', '2', '3', '4' }; // NOT USING
char temp_key[6];

int incl_key() {
    int i;
    FILE *fp;
    char code = "0";
    int control = 0;
    int var_internal = 0;

    fp = fopen("keys.bin", "wb");
    if (fp == NULL) {
        printf("\n Error opening file. \n");
    }

    printf("write your sequence <6 digits>:\n");

    do{
        scanf("%s", &temp_key);
        fputs(temp_key, fp);
        fputs("\n", fp);
        control++;
    } while (control < 5);
    fclose(fp);
}

int keys_db() {
    return 0;
}

int main() {
    incl_key();

    system("PAUSE");
}

提前致谢。

【问题讨论】:

  • 不清楚您的问题是什么或您的具体问题是什么。如果你想将它组织为“行”,为什么它是一个二进制文件?
  • 代码正在使用char temp_key[6]; scanf("%s", &amp;temp_key); 写入数组边界外并输入"123456"
  • 您的temp_key 有六个元素,并且您向我们展示了包含六个字符的示例数据。这意味着当您调用fputstemp_key 已满,并且不包含终止空字符。所以fputs 溢出数组,寻找那个空值,而你不知道写入文件的内容。定义 temp_key 并为终止 null 留出足够的空间,并确保您的 scanf 不会读取太多。
  • 你一般是fwritefread(或者没有文件流库,writeread)二进制文件。虽然您可以使用fputsstring(减去它的nul-terminating 字符)写入任何文件,但您写入的是ASCII 字符,而不是整数序列。 (例如1-bytechar,与一般4-bytesint
  • @chux 那么你的意思是我需要在向量中为 '\0' 或 '\n' 符号放置一个额外的空间吗?我只是想知道是否可以制作每个密码,每行存储一个 6 个字符,但我的代码很奇怪,我迷路了。如果这在二进制文件上是不可能的,例如,我如何浏览文件以寻找密码?扫描6个数字并与用户向量进行比较,但是如何?

标签: c file binary writing


【解决方案1】:

数组太小,用户输入为 字符串

char temp_key[6];
printf("write your sequence <6 digits>:\n");
scanf("%s", &temp_key);   // poor code

字符串是由第一个空字符终止并包括第一个空字符的连续字符序列。

当一种类型 12345 , 6, Enter, 将'1', '2', '3', '4', '5', '6', '\n' 放入@ 987654329@。 scanf("%s", temp_key); 查找前导空白,没有看到,然后读取 6 个非空白字符并将它们保存在 temp_key[0]temp_key[1]、...temp_key[5] 中。读取'\n'(一个空格),"%s" 指示停止扫描更多内容,将'\n' 放回stdin 以供以后输入,然后尝试附加一个空字符 em> 转换成temp_key[6] 使其成为字符串。但是temp_key[] 太小了,所以任何事情都可能发生 - 这是未定义的行为。剩下的代码无关紧要。

scanf("%s", &amp;temp_key); 是不正确的代码有 3 个原因。

  1. &amp;temp_key 在需要数组的第一个元素的地址来匹配"%s" 时传递数组的地址。这两个地址具有相同的值,但类型不同。这本身就是未定义的行为。然而绝大多数时候,它“工作”就像正确的scanf("%s", temp_key);(不是&amp;

  2. scanf("%s", temp_key); 对读取的数据量没有限制,如上所述,输入 6 位或更多位会导致缓冲区溢出和未定义行为

    李>
  3. 没有检查返回值,所以代码不知道事情是否成功。 stdin 可能已关闭(没有更多输入)或其他问题。

改为使用fgets() 读取用户输入的,并将该输入转换为字符串

#define KEY_N 6
//            key    \n   \0  extra - why be stingy? 
char temp_key[KEY_N + 1 + 1 + 10];

//scanf("%s", &temp_key);
if (fgets(temp_key, sizeof temp_key, stdin)) {
  // user input successfully read!

  temp_key[strcspn(temp_key), "\n"] = '\0'; // lop off potential trailing \n
  if (strlen(temp_key) != KEY_N) Handle_Invalid_Input();
  else GoodToGo();
}

代码也可能有其他问题。

例如:二进制与文本模式下的fp 以及“在 linux 上运行......所以我正在使用 Visual Studio”担心读取看起来像文本文件的“keys.bin”的期望。目前,只要将其视为二进制文件,OP 正在做的事情看起来就可以了。

【讨论】:

    猜你喜欢
    • 2011-04-03
    • 1970-01-01
    • 1970-01-01
    • 2022-10-15
    • 2013-04-28
    • 1970-01-01
    • 2018-08-18
    • 2010-12-13
    • 2015-05-02
    相关资源
    最近更新 更多