C 語言程式碼總結

qq_29506411發表於2020-12-04

/***************************************************************************
 * 正確在除錯過程中列印除錯資訊的方法  */
 
#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;
}
********************************************************************************************/

 

相關文章