我在创建一个代码时遇到了问题,该代码创建了一个包含多行的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");
}
提前致谢。
答案 0 :(得分:0)
数组对于用户输入而言太小,不能作为字符串。
char temp_key[6];
printf("write your sequence <6 digits>:\n");
scanf("%s", &temp_key); // poor code
string 是由第一个空字符终止并包含第一个空字符的连续字符序列。
当一个类型 1 , 2 , 3 , 4 , 5 , 6 ,输入,即'1'
,'2'
,'3'
,'4'
,'5'
,'6'
,'\n'
加入stdin
。 scanf("%s", temp_key);
查找前导空格,看不到,然后读取6个非空白字符并将其保存在temp_key[0]
,temp_key[1]
,.... temp_key[5]
。阅读'\n
&#39; (空格),"%s"
指示停止扫描更多内容,将'\n'
放回stdin
以供稍后输入,然后尝试追加空字符进入temp_key[6]
以使其成为字符串。但是temp_key[]
太小了,因此可能发生任何事情 - 它是未定义的行为。剩下的代码无关紧要。
scanf("%s", &temp_key);
是不正确的代码。
&temp_key
时, "%s"
传递数组的地址。这两个地址都具有相同的值,但类型不同。这本身就是未定义的行为。然而绝大多数时候,它的作用和#34;与正确的scanf("%s", temp_key);
(无&
)
scanf("%s", temp_key);
对读取的数据量没有限制,如上所述,输入6位或更多位数会导致缓冲区溢出和未定义的行为。
未检查返回值,因此代码不知道事情是否成功。 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
二进制vs文本模式以及&#34;在linux上运行...所以我使用Visual Studio&#34;关注阅读的期望&#34; keys.bin&#34;它看起来像一个文本文件。就目前而言,只要它被视为二进制文件,OP正在做的事情就好了。