Files
Data-Structure/VisualC++/Status/Status.c
2019-10-20 19:06:37 +08:00

165 lines
4.1 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include <stdio.h>
#include <string.h>
#include <stdarg.h> // 提供宏va_list、va_start、va_arg、va_end
#include <ctype.h> // 提供isprint原型
/*
* 这是自定义的数据录入函数用于从文件fp中读取格式化的输入
* 与fscanf不同之处在于此函数只会读取西文字符对于中文字符则会跳过
*
* 注:
* 1. 这里约定所有格式串为简单形式,如:%d%c%s等而不是%2d%5s等
* 2. 读取字符串时,遇到空格或非打印字符会停止读取
*/
int ReadData(FILE* fp, char* format, ...) {
int* i; // 存储读取到的整型
float* f; // 存储读取到的浮点型
char* ch; // 存储读取到的字符型
char* s; // 存储读取到的字符串型
int n; // 遍历存储字符串的字符数组
int len; // 格式串format的长度
int k; // 遍历格式串时的游标
int tmp; // 暂存从文件中读取到的字符
va_list ap; // 可变参数指针,指向存储数据的变量
// 累计成功读取到的字符数
int count = 0;
/*
* 获取格式串的长度
* 这里预设格式串仅由简单
*/
len = strlen(format);
// ap指向首个可变参数
va_start(ap, format);
// 只遍历奇数索引,因为偶数索引下都是%
for(k = 1; k <= len; k = k + 2) {
// 跳过所有非西文字符
while((tmp = getc(fp)) != EOF) {
// 遇到首个西文字符,将此西文字符重新放入输入流
if((tmp >= 0 && tmp <= 127)) {
ungetc(tmp, fp);
break;
}
}
// 如果已读到文件结尾,结束读取
if(tmp == EOF) {
break;
}
// 遇到了"%c",应该读取字符
if(format[k] == 'c') {
ch = va_arg(ap, char*);
count += fscanf(fp, "%c", ch);
}
// 遇到了"%d",应该读取整型
if(format[k] == 'd') {
i = va_arg(ap, int*);
while((tmp = getc(fp)) != EOF) {
// 寻找整数区域
if((tmp >= '0' && tmp <= '9') || tmp == '-' || tmp == '+') {
ungetc(tmp, fp);
break;
}
}
if(tmp != EOF) {
count += fscanf(fp, "%d", i);
}
}
// 读取浮点型一律存储为double类型
if(format[k] == 'f') {
f = va_arg(ap, float*);
while((tmp = getc(fp)) != EOF) {
if((tmp >= '0' && tmp <= '9') || tmp == '-' || tmp == '+' || tmp == '.') {
ungetc(tmp, fp);
break;
}
}
if(tmp != EOF) {
count += fscanf(fp, "%f", f);
}
}
// 读取字符串
if(format[k] == 's') {
s = va_arg(ap, char*);
n = 0;
// 查找排除空格的可打印字符
while((tmp = getc(fp)) != EOF && (!isprint(tmp) || tmp == ' ')) {
}
// 如果未到文件结尾
if(!feof(fp)) {
// 将上面读到的字符重新放入流中
ungetc(tmp, fp);
while((tmp = getc(fp)) != EOF) {
// 存储排除空格的可打印字符
if(isprint(tmp) && tmp != ' ') {
s[n++] = tmp;
} else {
ungetc(tmp, fp);
break;
}
}
count++;
}
// 字符串最后一个字符为空字符
s[n] = '\0';
}
}// for
va_end(ap);
return count;
}
// 摁下回车键以继续运行
void PressEnterToContinue() {
int debug = 1;
fflush(stdin);
printf("\nPress Enter to Continue...");
// 处于测试阶段时可以让debug=1自动添加换行便于测试
if(debug) {
printf("\n");
// 发布时可以让debug=0手动输入换行否则让程序暂停下来观察每一步的输出
} else {
getchar();
}
fflush(stdin);
}
// 函数暂停一段时间time不代表具体的时间
void Wait(long time) {
double i;
for(i = 0.01; i <= 100000.0 * time; i += 0.01) {
// 空循环
}
}