c - 找不到 __fpurge(stdin); 的替换
问题描述
我正在研究 C 中的文本文件主题,我有一个问题:我可以使用什么来代替,__fpurge(stdin);
但要让这个函数像这样工作,__fpurge(stdin);
并且我不允许包含<stdlib.h>
在这个程序中。我已经阅读了这个c - 需要 fflush 的替代方案,但只要我不被允许,#include <stdlib.h>
所以我不能使用strtol
.
void generateBill() {
FILE *fp, *fp1;
struct Bill t;
int id, found = 0, ch1, brel = 0;
char billname[40];
fp = fopen(fbill, "rb");
printf("ID\tName\tPrice\n\n");
while (1) {
fread(&t, sizeof(t), 1, fp);
if (feof(fp)) {
break;
}
printf("%d\t", t.pid);
printf("%s\t", t.pname);
printf("%d\t\t\t\n", t.pprice);
total = total + t.pprice;
}
printf("\n\n=================== Total Bill Amount %d\n\n", total);
fclose(fp);
if (total != 0) {
//__fpurge(stdin);
printf("\n\n\n Do you want to generate Final Bill[1 yes/any number to no]:");
scanf("%d", &ch1);
if (ch1 == 1) {
brel = billFileNo();
sprintf(billname, "%s%d", " ", brel);
strcat(billname, "dat");
fp = fopen(fbill, "rb");
fp1 = fopen(billname, "wb");
while (1) {
fread(&t, sizeof(t), 1, fp);
if (feof(fp)) {
break;
}
fwrite(&t, sizeof(t), 1, fp1);
}
fclose(fp);
fclose(fp1);
fp = fopen(fbill, "wb");
fclose(fp);
}
total = 0;
}
}
解决方案
__fpurge
是仅在某些系统(glibc 2.1.95、IBM zOS...)上可用的非标准函数,它丢弃读取到流缓冲区中尚未被getc()
.
正如linux 手册页中所解释的,通常想要丢弃输入缓冲区是错误的。
您使用 读取用户输入scanf()
,它会在请求的转换完成时停止扫描输入,例如,%d
当它读取无法继续数字的字符并将该字符留在输入流中时停止读取用户键入的字符。由于stdin
连接到终端时通常是行缓冲的,因此您应该在处理输入后读取并丢弃用户输入的行中的任何剩余字节。
这是一个用于此目的的简单函数:
int flush_input(FILE *fp) {
int c;
while ((c = getc(fp)) != EOF && c != '\n')
continue;
return c;
}
您将在处理用户输入后调用此函数,并且您应该测试 的返回值scanf()
以确保用户输入具有预期的语法。
这是您功能的修改版本:
#include <errno.h>
#include <string.h>
// return a non zero error code in case of failure
int generateBill(void) {
FILE *fp, *fp1;
struct Bill t;
int id, found = 0, ch1, brel = 0;
char billname[40];
fp = fopen(fbill, "rb");
if (fp == NULL) {
fprintf(sdterr, "cannot open %s: %s\n", fbill, strerror(errno));
return 1;
}
printf("ID\tName\tPrice\n\n");
while (fread(&t, sizeof(t), 1, fp) == 1) {
printf("%d\t", t.pid);
printf("%s\t", t.pname);
printf("%d\t\t\t\n", t.pprice);
total = total + t.pprice;
}
printf("\n\n=================== Total Bill Amount %d\n\n", total);
if (total != 0) {
int res;
printf("\n\n\n Do you want to generate Final Bill[1 yes/any number to no]:");
while ((res = scanf("%d", &ch1)) == 0) {
fprintf("Invalid input. Try again\n");
flush_input(stdin);
}
flush_input(stdin);
if (res == EOF) {
fprintf("premature end of file on input\n");
fclose(fp);
return 2;
}
if (ch1 == 1) {
brel = billFileNo();
snprintf(billname, sizeof billname, "bill-%d-dat", brel);
rewind(fp);
fp1 = fopen(billname, "wb");
if (fp1 == NULL) {
fprintf(sdterr, "cannot open %s: %s\n", billname, strerror(errno));
fclose(fp);
return 1;
}
while (fread(&t, sizeof(t), 1, fp) == 1) {
fwrite(&t, sizeof(t), 1, fp1);
}
fclose(fp1);
}
}
fclose(fp);
return 0;
}
推荐阅读
- javascript - 如何获取在 Chrome 标签中播放的音频名称
- javascript - 在 div 外部单击应该为 div 添加抖动效果;点击里面不应该有任何变化
- discord.py - 将排行榜分为页面 discord.py
- javascript - 顺序 API 调用,我使用 Promise.all 还是迭代函数?
- google-apps-script - Google 表格:具有动态变化的自定义功能
- javascript - TypeError:SnakeGame 不是构造函数
- php - 将旧的 mysql 调用重写为新的 mysqli_real_query
- amazon-web-services - 发送 POST 请求返回“文本为空”
- javascript - 如何获得全时使用 Javascript 显示
- javascript - 如何在不忽略重定向的情况下将道具传递给私有路由