gpt4 book ai didi

c - 使用getchar()和空白填充进行安全编码

转载 作者:行者123 更新时间:2023-11-30 15:27:18 25 4
gpt4 key购买 nike

这部分代码是较大项目的一部分。我告诉你这是因为它很重要。我正在使用小型(代码方式)数据库来跟踪我的所有照片。我正在设计它,以便以后可以扩展程序以将引文存储在我的所有论文中。

不管是好是坏,我都选择了一个具有固定宽度字段的简单平面文件系统。这可能不是最有效的内存使用方式,并且文件大小变得不完整,但是它具有一些超级优点:没有定界符,因此文件以良好的格式轻松保持可读性,并可以通过简单的数组索引轻松访问数组。

我喜欢最后一部分,特别是因为它属于我的技能范围。
关于该数据库的一件事是,我需要能够进行很多输入FAAAA…ST!瓶颈出现在用户输入部分,而不是内存,而不是磁盘空间中,因此我专注于使输入错误变得快速而容易。

我了解到在C语言中获取用户输入可能是一件棘手的事情。 C的字符串处理库具有许多可被利用来生成缓冲区溢出的功能。因此,对于此代码,我实现了Robert C. Seacord在C和C ++中的安全编码的一些建议,特别是“字符串和缓冲区溢出”一章。

这是链接:http://www.informit.com/articles/article.aspx?p=2036582&seqNum=5

Seacord建议使用fgets()处理输入行,尽管可以安全地进行,但存在性能限制。 (我喜欢快速。不是吗?)他进一步建议使用getchar()代替。那就是我所做的。

这是他建议使用while循环安全地使用getchar()的建议:

while(( (ch = getchar()) != \n) && ch != EOF)


在下面的代码中,我调整了一下。

我需要执行I / O几件事。首先,如果输入的内容太长,我希望将其截断。即使我可能是唯一的用户,也可能会犯一个错误。其次,如果输入的长度小于字段宽度(主要是这种情况),我想在该字段的右边填充空格。

那就是我的问题。稍作讨论。

此空格使Flatfile保持外观整洁,并且使索引编制极为容易。我只需要按一下Enter键,然后依次进入下一个条目,就知道计算机已经按照我想要的方式格式化了数据。

(这实际上是E.F. Codd的粗略实现,即必须屏蔽数据以防止直接访问。在存储之前,必须检查,精炼,解析所有内容。这可以防止数据损坏。)

在这段代码中,我切掉了所有的内容,因为那只是噪音,我非常讨厌尝试阅读其他人的代码,这些人发布了整个该死的程序,并带有各种无关紧要的内容,而不仅仅是给他们造成麻烦的部分。同时,我想发布一个完整的程序,可以选择,复制,粘贴,保存和编译该程序。所以我在这里做了。我留下了注释和小检查,以确保一切都正常,然后再注释掉,所以这不是最简单的代码,但是爱因斯坦的那句简单的话又叫什么呢?

无论如何,我知道所有这一切都有些长,但是我想勾勒出我所使用的设计原则。您可能会有有用的评论。我确信地狱可能会采取愚蠢的做法。

我遇到的确切问题就是如何用正确数量的空格填充这些字段。

我确实找到了解决方案。有点。

但这对我来说似乎是hack。

我只是怀疑有一种更有效,快速或优雅的方法来完成我想做的事情。 “ hack”部分正在调用第二个打印函数,并使用字符计数和maxlength常数之间的差在数据后添加空格。参见27-39行。可行...但是?

我不应该能够直接填充阵列吗?

无法解决!

这是代码:

#include <stdio.h>
#include <stdlib.h>

/** array-ops/5.c
Template for inputting data from stdin using getchar().
Sets arraymax to prevent overflow, truncates array if smaller than
arraymax, right pads short entries with spaces, and quits gracefully.
(Really? You're /sure/ about that last?) */

#define ARRAYMAX 8

int main(int argc, char *argv[])
{
int ch;
int count;
char array[ARRAYMAX];

ch = getchar();
count = 0;
// no overflows, unclosed processes, or extra keystrokes needed
while(count < ARRAYMAX && ch != '\n' && ch != EOF) {
array[count++] = ch;

ch = getchar();
}

int diff = (ARRAYMAX - count);
//printf("count: %d\n", count); // check
//printf("diff: %d\n", diff); // check again. off-by-one?

int i;
for(i = 0; i < count; i++) {
printf("%c", array[i]);
}

int j;
for(j = 0; j < diff; j++) {
printf("%s", " ");
}

//printf("|\n"); // check, spaces really there?
printf("\n");

return 0;
}


顺便说一句,我真的在发布之前搜索了答案。随时用羽毛来敲我,但似乎每个人都在尝试解决一个稍有不同的问题,尤其是对数据保护和缓冲区溢出的冷漠态度。因此,我认为这不是重复的问题。

[编辑]这是修改后的代码。它结合了Joachim的解决方案和if-else循环以隔离截断的字符串。仍然不是最好的,但是...

#include <stdio.h>
#include <stdlib.h>

/** array-ops/5r.c
Template for inputting data from stdin using getchar().
Sets arraymax to prevent overflow, truncates array if smaller than
arraymax, right pads short entries with spaces, and quits gracefully. */

#define ARRAYMAX 8

int main(int argc, char *argv[])
{
int ch;
int count;
char array[ARRAYMAX];

ch = getchar();
count = 0;
// no overflows, unclosed processes, or extra keystrokes needed
while(count < ARRAYMAX && ch != '\n' && ch != EOF) {
array[count++] = ch;

ch = getchar();
}

int diff = (ARRAYMAX - count);
printf("count: %d\n", count); // check
printf("diff: %d\n", diff); // check again for off-by-one

if(count == ARRAYMAX) {
printf("%.*s", ARRAYMAX, array);
} else {
printf("%.*s%*c", count, array, diff, ' ');
}

printf("|--array ends there\n"); // check, spaces really there?
//printf("\n");

return 0;
}

最佳答案

如果您看到例如this printf reference,您可能会注意到*格式修饰符,该修饰符可用于通过参数设置字段宽度或精度。

可以使用如

printf("%.*s%*c\n", count, array, diff, ' ');


这将从 count打印 array字符,然后打印一个以 diff字符右对齐的空格,并以换行符结尾。

对于例如 "ab\n",它应打印 "ab ",后跟换行符。

关于c - 使用getchar()和空白填充进行安全编码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27074131/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com