/***************************************************************************
* 正确在调试过程中打印调试信息的方法 */
#include <stdio.h>
#define Lin_Dbg // 可以在编译时用 gcc -Wall -DLin_Dbg main.c 代替
#ifdef Lin_Dbg
#define PDBG(fmt, args...) printf("Dbg: " fmt, ## args)
#else
#define PDBG(fmt, args...) // empty debug slot // 因为这里是宏定义,如果不需要打印信息,就不用调用函数了
#endif
int main(void)
{
PDBG("%s:%d:%s\n", __FILE__, __LINE__, __func__); // Dbg: main.c:13:main
// 上面语句用 gcc 的 -E 选项预编译后为:printf("Dbg: " "%s:%d:%s\n", "main.c", 17, __func__);
return 0;
}
/*************************************************************************************/
/*************************************************************************************
* 对两个排序文件,以排序的方式组合到一个新文件
#include <stdio.h>
#include <assert.h>
#define ENDF EOF // window编译要定义为 0x0a , 但在 MINGW64 下编译需要定义为 EOF
//#define __DEBUG__ // 编译时定义: gcc -Wall -D__DEBUG__ main.c
#ifdef __DEBUG__ // 为了只在调试过程中打印信息,打印调试信息个数和 printf() 函数一样,
// 只是函数名变成了 debug
#include <stdarg.h>
void debug(const char* fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vprintf(fmt, ap);
va_end(ap);
}
#else
void debug(const char* fmt, ...) {} // 即使没有打印,函数调用也发生了,如果信息打印太多了,会影响程序的性能
#endif
int main(void)
{
FILE *fp1, *fp2, *fp3;
int c1, c2;
fp1 = fopen("./f1.txt", "r");
assert(fp1 != NULL); // 发生断言后会把当前位置打印在终端
fp2 = fopen("./f2.txt", "r");
assert(fp2 != NULL);
fp3 = fopen("./f3.txt", "w+");
assert(fp3 != NULL);
while( (c1 = fgetc(fp1)) != ENDF && (c2 = fgetc(fp2)) != ENDF)
{
debug("c1 = %x, c2 = %x\n", c1, c2);
if (c1 <= c2)
{
debug("\tAdd c1 to f3, return c2 to f2\n");
fputc(c1, fp3);
ungetc(c2, fp2); // 将字符回退到文件流,注意和 fputc() 函数的区别
}
else
{
debug("\tAdd c2 to f3, return c1 to f1\n");
fputc(c2, fp3);
ungetc(c1, fp1);
}
}
if (c1 == ENDF)
{
debug("c1 already finished\n");
while((c2 = fgetc(fp2)) != ENDF)
fputc(c2, fp3);
if (c2 == ENDF)
debug("c2 already finished\n");
}
else if (c2 == ENDF)
{
debug("c2 already finished\n");
do{
fputc(c1, fp3);
} while((c1 = fgetc(fp1)) != ENDF);
if (c1 == ENDF)
debug("c1 already finished\n");
}
debug("Both of the files finished\n");
rewind(fp3); // 把文件指针指向文件头
while((c1 = fgetc(fp3)) != EOF) // 为什么 windows 下前面用 EOF 判断不行,这里可以呢?
putc(c1, stdout);
fclose(fp1); // 记得及时关闭文件
fclose(fp2);
fclose(fp3);
return 0;
}
************************************************************************************************/
/****************************************************************************
* 5个学生,每个学生3门课程,从键盘输入(学号,姓名,三门成绩)
* 然后计算出平均成绩,并保存到磁盘
#include <stdio.h>
#include <assert.h>
#define NUM_STD 5
typedef struct Std{
unsigned int sID;
unsigned char sName[20];
float sco1;
float sco2;
float sco3;
float aver;
} Std;
int main(void)
{
Std std[NUM_STD];
int i = 0;
FILE* fp;
for (; i < NUM_STD; i++)
{
printf("Please input std[%d]: ", i);
scanf("%d %s %f %f %f", &std[i].sID, std[i].sName, &std[i].sco1, &std[i].sco2, &std[i].sco3);
std[i].aver = (std[i].sco1 + std[i].sco2 + std[i].sco3) / 3;
}
fp = fopen("./test.txt", "w+");
assert(fp);
for (i = 0; i < NUM_STD; i++)
{
printf("std[%d]: %8d %20s %5.1f %5.1f %5.1f %5.1f\n", i, std[i].sID, std[i].sName, std[i].sco1, std[i].sco2, std[i].sco3, std[i].aver);
fprintf(fp, "std[%d]: %8d %20s %5.1f %5.1f %5.1f %5.1f\n", i, std[i].sID, std[i].sName, std[i].sco1, std[i].sco2, std[i].sco3, std[i].aver);
}
fclose(fp);
return 0;
}
********************************************************************************************/