一些C语言小程序
2015-03-08
c语言的文件操作
文件操作是软件写作的基本功之一,这里从网上找了相关教程。自己联系了下,总结写在这里,以便将来复习参考。
stido.h 头文件中包含了 FILE 这个结构的声明,这是一个用于访问流的数据结构。对于没有ANSI程序,最少包含三个流:stdin, stdout, stderr, 他们都指向一个FILE结构的指针。
标准流的IO更为简单,因为他们不需要打开关闭函数。IO以三种基本形式处理数据:
- 字符: getchar, putchar
- 文本行:gets/puts, scanf/printf
- 二进制数据:fread/fwrite
perror函数提供一种向用户报告错误的简单方法。
C语言中没有输入输出语句,所有的输入输出功能都用 ANSI C提供的一组标准库函数来实现。文件操作标准库函数有:
- 文件的打开操作
    fopen 打开一个文件 
- 文件的关闭操作
    fclose 关闭一个文件 
- 文件的读写操作
    fgetc 从文件中读取格式化一个字符 fputc 写一个字符到文件中去 fgets 从文件中读取一个字符串 fputs 写一个字符串到文件中去 fprintf 往文件中写格式化数据 fscanf 格式化读取文件中数据 fread 以二进制形式读取文件中的数据 fwrite 以二进制形式写数据到文件中去 getw 以二进制形式读取一个整数 putw 以二进制形式存贮一个整数 
- 文件状态检查函数
    feof 文件结束 ferror 文件读/写出错 clearerr 清除文件错误标志 ftell 了解文件指针的当前位置 
- 文件定位函数
    rewind 反绕 fseek 随机定位 getcwd c库函数获取当前路径 char* getcwd(char buffer, size_t size) mkdir 创建目录 mkdir(char name, int mode) 
1. 文件的打开
1.函数原型
FILE *fopen(char *pname,char *mode) #### 2.功能说明 按照mode 规定的方式,打开由pname指定的文件。若找不到由pname指定的相应文件,就按以下方式之一处理:
- (1) 此时如mode 规定按写(w)方式打开文件,就按由pname指定的名字建立一个新文件;
- (2) 此时如mode 规定按读(r)方式打开文件,就会产生一个错误。
打开文件的作用是:
- (1)分配给打开文件一个FILE 类型的文件结构体变量,并将有关信息填入文件结构体变量;
- (2)开辟一个缓冲区;
- (3)调用操作系统提供的打开文件或建立新文件功能,打开或建立指定文件; FILE *:指出fopen是一个返回文件类型的指针函数;
3.参数说明
- pname:是一个字符指针,它将指向要打开或建立的文件的文件名字符串。
- mode:是一个指向文件处理方式字符串的字符指针。所有可能的文件处理方式如下:
| 格式 | 读 | 写 | 追加 | 
| 文本 | r | w | a | 
| 二进制 | rb | wb | ab | 
4.返回值
- 正常返回:被打开文件的文件指针。
- 异常返回:NULL,表示打开操作不成功。
2. 文件的关闭
1.函数原型
int fclose(FILE *fp); #### 2. 功能说明   关闭由fp指出的文件。此时调用操作系统提供的文件关闭功能,关闭由fp->fd指出的文件;释放由fp指出的文件类型结构体变量;返回操作结果,即0或EOF。
3. 参数说明
fp:一个已打开文件的文件指针。
4. 返回值
正常返回:0。 异常返回:EOF,表示文件在关闭时发生错误。
3. 文件读写
函数原型:
int fgetc(FILE *fp); int fputc(int ch,FILE *fp); char *fgets(char *str,int n,FILE *fp); int fputs(char *str,FILE *fp); int fprintf(FILE *fp,char *format,arg_list); int fread(void *buffer,unsigned sife,unsigned count,FILE *fp); int fwrite(void *buffer,unsigned sife,unsigned count,FILE *fp); int getw(FILE *fp); int putw(int n,FILE *fp);
时间编程
高通平台下耳机驱动的初始化分析
从高通8x20平台以来,高通耳机驱动模块引入了MBHC这样一个耳机检测机制。这个机制中需要用户去设定一堆的值,然后通过初始化的调用写到相应的寄存器中。本来有一大堆的数据结构要去kmalloc/kzmalloc(对应应用程序中是malloc/zalloc),高通的软件工程师巧妙的借用了C语言的数据指针转化和内存定位来完成这个工作,当时读这一段代码时,非常受益。攒到下面,有机会也在自己的代码中借用下。
/*
 * qcom headset data struct initialition
 */
#include<stdio.h>
#include<stdlib.h>
typedef short s16;
typedef unsigned short u16;
typedef int s32;
typedef unsigned int u32;
typedef char s8;
typedef unsigned char u8;
typedef s16 INT16;
typedef u16 UINT16;
typedef s32 INT32;
typedef u32 UINT32;
typedef s8 CHAR8;
typedef u8 UCHAR8;
#define WCD9XXX_MBHC_DEF_BUTTONS 8
#define WCD9XXX_MBHC_DEF_RLOADS  5
enum wcd9xxx_micbias_num {
	MBHC_MICBIAS_INVALID = -1,
	MBHC_MICBIAS1,
	MBHC_MICBIAS2,
	MBHC_MICBIAS3,
	MBHC_MICBIAS4,
};
enum wcd9xxx_mbhc_clk_freq {
	TAIKO_MCLK_12P2MHZ = 0,
	TAIKO_MCLK_9P6MHZ,
	TAIKO_NUM_CLK_FREQS,
};
enum tapan_pid_current {
	TAPAN_PID_MIC_2P5_UA,
	TAPAN_PID_MIC_5_UA,
	TAPAN_PID_MIC_10_UA,
	TAPAN_PID_MIC_20_UA,
};
  
enum wcd9xxx_mbhc_btn_det_mem {
	MBHC_BTN_DET_V_BTN_LOW,
	MBHC_BTN_DET_V_BTN_HIGH,
	MBHC_BTN_DET_N_READY,
	MBHC_BTN_DET_N_CIC,
	MBHC_BTN_DET_GAIN
};
struct wcd9xxx_mbhc_general_cfg {
	u8 t_ldoh;
	u8 t_bg_fast_settle;
	u8 t_shutdown_plug_rem;
	u8 mbhc_nsa;
	u8 mbhc_navg;
	u8 v_micbias_l;
	u8 v_micbias;
	u8 mbhc_reserved;
	u16 settle_wait;
	u16 t_micbias_rampup;
	u16 t_micbias_rampdown;
	u16 t_supply_bringup;
} __attribute__((packed));
struct wcd9xxx_mbhc_plug_detect_cfg {
	u32 mic_current;
	u32 hph_current;
	u16 t_mic_pid;
	u16 t_ins_complete;
	u16 t_ins_retry;
	u16 v_removal_delta;
	u8 micbias_slow_ramp;
	u8 reserved0;
	u8 reserved1;
	u8 reserved2;
} __attribute__((packed));
struct wcd9xxx_mbhc_plug_type_cfg {
	u8 av_detect;
	u8 mono_detect;
	u8 num_ins_tries;
	u8 reserved0;
	s16 v_no_mic;
	s16 v_av_min;
	s16 v_av_max;
	s16 v_hs_min;
	s16 v_hs_max;
	u16 reserved1;
} __attribute__((packed));
struct wcd9xxx_mbhc_btn_detect_cfg {
	s8 c[8];
	u8 nc;
	u8 n_meas;
	u8 mbhc_nsc;
	u8 n_btn_meas;
	u8 n_btn_con;
	u8 num_btn;
	u8 reserved0;
	u8 reserved1;
	u16 t_poll;
	u16 t_bounce_wait;
	u16 t_rel_timeout;
	s16 v_btn_press_delta_sta;
	s16 v_btn_press_delta_cic;
	u16 t_btn0_timeout;
	s16 _v_btn_low[0]; /* v_btn_low[num_btn] */
	s16 _v_btn_high[0]; /* v_btn_high[num_btn] */
	u8 _n_ready[TAIKO_NUM_CLK_FREQS];
	u8 _n_cic[TAIKO_NUM_CLK_FREQS];
	u8 _gain[TAIKO_NUM_CLK_FREQS];
} __attribute__((packed));
struct wcd9xxx_mbhc_imped_detect_cfg {
	u8 _hs_imped_detect;
	u8 _n_rload;
	u8 _hph_keep_on;
	u8 _repeat_rload_calc;
	u16 _t_dac_ramp_time;
	u16 _rhph_high;
	u16 _rhph_low;
	u16 _rload[0]; /* rload[n_rload] */
	u16 _alpha[0]; /* alpha[n_rload] */
	u16 _beta[3];
} __attribute__((packed));
#define WCD9XXX_MBHC_CAL_SIZE(buttons, rload) ( \
	sizeof(enum wcd9xxx_micbias_num) + \
	sizeof(struct wcd9xxx_mbhc_general_cfg) + \
	sizeof(struct wcd9xxx_mbhc_plug_detect_cfg) + \
	    ((sizeof(s16) + sizeof(s16)) * buttons) + \
	sizeof(struct wcd9xxx_mbhc_plug_type_cfg) + \
	sizeof(struct wcd9xxx_mbhc_btn_detect_cfg) + \
	sizeof(struct wcd9xxx_mbhc_imped_detect_cfg) + \
	    ((sizeof(u16) + sizeof(u16)) * rload) \
	)
#define WCD9XXX_MBHC_CAL_GENERAL_PTR(cali) ( \
	    (struct wcd9xxx_mbhc_general_cfg *) cali)
#define WCD9XXX_MBHC_CAL_PLUG_DET_PTR(cali) ( \
	    (struct wcd9xxx_mbhc_plug_detect_cfg *) \
	    &(WCD9XXX_MBHC_CAL_GENERAL_PTR(cali)[1]))
#define WCD9XXX_MBHC_CAL_PLUG_TYPE_PTR(cali) ( \
	    (struct wcd9xxx_mbhc_plug_type_cfg *) \
	    &(WCD9XXX_MBHC_CAL_PLUG_DET_PTR(cali)[1]))
#define WCD9XXX_MBHC_CAL_BTN_DET_PTR(cali) ( \
	    (struct wcd9xxx_mbhc_btn_detect_cfg *) \
	    &(WCD9XXX_MBHC_CAL_PLUG_TYPE_PTR(cali)[1]))
#define WCD9XXX_MBHC_CAL_IMPED_DET_PTR(cali) ( \
	    (struct wcd9xxx_mbhc_imped_detect_cfg *) \
	    (((void *)&WCD9XXX_MBHC_CAL_BTN_DET_PTR(cali)[1]) + \
	     (WCD9XXX_MBHC_CAL_BTN_DET_PTR(cali)->num_btn * \
	      (sizeof(WCD9XXX_MBHC_CAL_BTN_DET_PTR(cali)->_v_btn_low[0]) + \
	       sizeof(WCD9XXX_MBHC_CAL_BTN_DET_PTR(cali)->_v_btn_high[0])))) \
	)
void *wcd9xxx_mbhc_cal_btn_det_mp(
			    const struct wcd9xxx_mbhc_btn_detect_cfg *btn_det,
			    const enum wcd9xxx_mbhc_btn_det_mem mem)
{
	void *ret = &btn_det->_v_btn_low;
	switch (mem) {
	case MBHC_BTN_DET_GAIN:
		ret += sizeof(btn_det->_n_cic);
	case MBHC_BTN_DET_N_CIC:
		ret += sizeof(btn_det->_n_ready);
	case MBHC_BTN_DET_N_READY:
		ret += sizeof(btn_det->_v_btn_high[0]) * btn_det->num_btn;
	case MBHC_BTN_DET_V_BTN_HIGH:
		ret += sizeof(btn_det->_v_btn_low[0]) * btn_det->num_btn;
	case MBHC_BTN_DET_V_BTN_LOW:
		/* do nothing */
		break;
	default:
		ret = NULL;
	}
	return ret;
}
void* def_tapan_mbhc_cal(void)
{
	void *tapan_cal;
	struct wcd9xxx_mbhc_btn_detect_cfg *btn_cfg;
	u16 *btn_low, *btn_high;
	u8 *n_ready, *n_cic, *gain;
	tapan_cal = malloc(WCD9XXX_MBHC_CAL_SIZE(WCD9XXX_MBHC_DEF_BUTTONS,
						WCD9XXX_MBHC_DEF_RLOADS));
	if (!tapan_cal) {
		printf("%s: out of memory\n", __func__);
		return NULL;
	}
#define S(X, Y) ((WCD9XXX_MBHC_CAL_GENERAL_PTR(tapan_cal)->X) = (Y))
#define P(X) (printf(#X " = %d\n",WCD9XXX_MBHC_CAL_GENERAL_PTR(tapan_cal)->X))
	S(t_ldoh, 100);
	S(t_bg_fast_settle, 100);
	S(t_shutdown_plug_rem, 255);
	S(mbhc_nsa, 2);
	S(mbhc_navg, 128);
	P(t_ldoh);
	P(t_bg_fast_settle);
	P(t_shutdown_plug_rem);
	P(mbhc_nsa);
	P(mbhc_navg);
#undef P
#undef S
#define S(X, Y) ((WCD9XXX_MBHC_CAL_PLUG_DET_PTR(tapan_cal)->X) = (Y))
#define P(X) (printf(#X " = %d\n",WCD9XXX_MBHC_CAL_PLUG_DET_PTR(tapan_cal)->X))
	S(mic_current, TAPAN_PID_MIC_5_UA);
	S(hph_current, TAPAN_PID_MIC_5_UA);
	S(t_mic_pid, 100);
	S(t_ins_complete, 250);
	S(t_ins_retry, 200);
	P(mic_current);
	P(hph_current);
	P(t_mic_pid);
	P(t_ins_complete);
	P(t_ins_retry);
#undef P
#undef S
#define S(X, Y) ((WCD9XXX_MBHC_CAL_PLUG_TYPE_PTR(tapan_cal)->X) = (Y))
#define P(X) (printf(#X " = %d\n",WCD9XXX_MBHC_CAL_PLUG_TYPE_PTR(tapan_cal)->X))
	S(v_no_mic, 30);
	S(v_hs_max, 2450);
	P(v_no_mic);
  P(v_hs_max);
#undef P
#undef S
#define S(X, Y) ((WCD9XXX_MBHC_CAL_BTN_DET_PTR(tapan_cal)->X) = (Y))
#define P(X) (printf(#X " = %d\n", WCD9XXX_MBHC_CAL_BTN_DET_PTR(tapan_cal)->X))
	S(c[0], 62);
	S(c[1], 124);
	S(nc, 1);
	S(n_meas, 5);
	S(mbhc_nsc, 10);
	S(n_btn_meas, 1);
	S(n_btn_con, 2);
	S(num_btn, WCD9XXX_MBHC_DEF_BUTTONS);
	S(v_btn_press_delta_sta, 100);
	S(v_btn_press_delta_cic, 50);
	P(c[0]);
	P(c[1]);
	P(nc);
	P(n_meas);
	P(mbhc_nsc);
	P(n_btn_meas);
	P(n_btn_con);
	P(num_btn);
	P(v_btn_press_delta_sta);
	P(v_btn_press_delta_cic);
#undef P
#undef S
	btn_cfg = WCD9XXX_MBHC_CAL_BTN_DET_PTR(tapan_cal);
	btn_low = wcd9xxx_mbhc_cal_btn_det_mp(btn_cfg, MBHC_BTN_DET_V_BTN_LOW);
	btn_high = wcd9xxx_mbhc_cal_btn_det_mp(btn_cfg,
					       MBHC_BTN_DET_V_BTN_HIGH);
	btn_low[0] = -50;
	btn_high[0] = 20;
	btn_low[1] = 21;
	btn_high[1] = 61;
	btn_low[2] = 62;
	btn_high[2] = 104;
	btn_low[3] = 105;
	btn_high[3] = 148;
	btn_low[4] = 149;
	btn_high[4] = 189;
	btn_low[5] = 190;
	btn_high[5] = 228;
	btn_low[6] = 229;
	btn_high[6] = 269;
	btn_low[7] = 270;
	btn_high[7] = 500;
	n_ready = wcd9xxx_mbhc_cal_btn_det_mp(btn_cfg, MBHC_BTN_DET_N_READY);
	n_ready[0] = 80;
	n_ready[1] = 12;
	n_cic = wcd9xxx_mbhc_cal_btn_det_mp(btn_cfg, MBHC_BTN_DET_N_CIC);
	n_cic[0] = 60;
	n_cic[1] = 47;
	gain = wcd9xxx_mbhc_cal_btn_det_mp(btn_cfg, MBHC_BTN_DET_GAIN);
	gain[0] = 11;
	gain[1] = 14;
	return tapan_cal;
}
int main(int argc, char* argv[])
{
	def_tapan_mbhc_cal();
	return 0;
}
动态数组
1.这个程序介绍动态数据的用法。接受用户的输入数据,升序排列后打印。
#include<stdio.h>
#include<stdlib.h>
int compare_intergers(void const *a,void const *b)
{
  register int const *pa = a;
  register int const *pb = b;
  return *pa > *pb ? 1 : ( *pa < *pb ? -1 : 0 );
}
int main()
{
  int *array;
  int n_values;
  int i;
  printf("How many values are there?\n");
  if( (scanf("%d",&n_values) != 1) || n_values < 0){
    printf("Iligeal number of values.\n");
    exit(EXIT_FAILURE);
  }
  array = malloc(sizeof(n_values) * sizeof(int));
  if(array == NULL){
    printf("Failed to allloc the memory!\n");
    exit(EXIT_FAILURE);
  }
  for(i=0;i< n_values;i++){
    printf("? ");
    if(scanf("%d",array + i) != 1){
      printf("Error reading values %d\n",i);
      free(array);
      exit(EXIT_FAILURE);
    }
  }
  qsort(array,n_values,sizeof(int),compare_intergers);
  for(i=0;i<n_values;i++){
    printf("%d\n",array[i]);
  }
  free(array);
  return EXIT_SUCCESS;
}

