现在的位置: 首页 > 综合 > 正文

问题集锦(26-29)

2014年03月21日 ⁄ 综合 ⁄ 共 2939字 ⁄ 字号 评论关闭

Problem26 how to use access() function?

Ans:

函数原型:

intaccess(const char *pathname, int mode);

判断一个文件是否存在:

if(access(“finame.txt”,F_OK) == 0)

{

printf(“filename.txt已存在”);

}

The modespecifies the accessibility check(s) to be performed, and is

either thevalue F_OK, or a mask consisting of the bitwise OR of one or

moreof R_OK, W_OK, and X_OK. F_OK tests for the existence of the

file. R_OK, W_OK, and X_OK test whether the file exists and grants

read,write, and execute permissions, respectively.

PS:

/*

*Strip blanks from a string.

*Return a pointer into the provided string.

*Modifies input adding a NULL at first

*of trailing blanks.“除头斩尾”

*/

char*

lpc_strip_blanks(char*input)

{

char*iptr;

/*Find first non-blank */

while(*input&& isspace(*input)) ++input;

/*Find last non-blank */

iptr=input+strlen(input);

if(iptr > input) {

while(isspace(*--iptr));

*(iptr+1)='\0';

}

returninput;

}

Problem27 How to install a new font in Linux?

Ans;

step1:copynew font file “font.tty” to a directory in linux.

step2:chmod755 font.tty

step3:mkfontscale

step4:mkfontdir

step5:fc-cache

Problem28:C语言中如何使用宏

Ans:

C(和C++)中的宏(Macro)属于编译器预处理的范畴,属于编译期概念(而非运行期概念)。下面对常遇到的宏的使用问题做了简单总结。

关于###

C语言的宏中,#的功能是将其后面的宏参数进行字符串化操作(Stringfication),简单说就是在对它所引用的宏变量通过替换后在其左右各加上一个双引号。比如下面代码中的宏:

#define WARN_IF(EXP) \

do{ if (EXP) \

fprintf(stderr,"Warning: " #EXP "\n"); } \

while(0)

那么实际使用中会出现下面所示的替换过程:

WARN_IF (divider ==0);

被替换为

do {

if (divider ==0)

fprintf(stderr,"Warning" "divider == 0" "\n");

} while(0);

这样每次divider(除数)为0的时候便会在标准错误流上输出一个提示信息。

##被称为连接符(concatenator),用来将两个Token连接为一个Token。注意这里连接的对象是Token就行,而不一定是宏的变量。比如你要做一个菜单项命令名和函数指针组成的结构体的数组,并且希望在函数名和菜单项命令名之间有直观的、名字上的关系。那么下面的代码就非常实用:

struct command

{

char * name;

void (*function)(void);

};

#defineCOMMAND(NAME) { NAME, NAME ## _command }

//然后你就用一些预先定义好的命令来方便的初始化一个command结构的数组了:

structcommandcommands[]={

COMMAND(quit),

COMMAND(help),

...

}

COMMAND宏在这里充当一个代码生成器的作用,这样可以在一定程度上减少代码密度,间接地也可以减少不留心所造成的错误。我们还可以n##符号连接n+1Token,这个特性也是#符号所不具备的。比如:

#defineLINK_MULTIPLE(a,b,c,d) a##_##b##_##c##_##d

typedefstruct_record_typeLINK_MULTIPLE(name,company,position,salary);

//这里这个语句将展开为:

// typedef struct_record_type name_company_position_salary;

关于...的使用

...C宏中称为VariadicMacro,也就是变参宏。比如:

#definemyprintf(templt,...) fprintf(stderr,templt,__VA_ARGS__)

//或者

#definemyprintf(templt,args...)fprintf(stderr,templt,args)

第一个宏中由于没有对变参起名,我们用默认的宏__VA_ARGS__来替代它。第二个宏中,我们显式地命名变参为args,那么我们在宏定义中就可以用args来代指变参了。同C语言的stdcall一样,变参必须作为参数表的最有一项出现。当上面的宏中我们只能提供第一个参数templt时,C标准要求我们必须写成:

myprintf(templt,);

的形式。这时的替换过程为:

myprintf("Error!\n",);

替换为:

fprintf(stderr,"Error!\n",);

这是一个语法错误,不能正常编译。这个问题一般有两个解决方法。首先,GNUCPP提供的解决方法允许上面的宏调用写成:

myprintf(templt);

而它将会被通过替换变成:

fprintf(stderr,"Error!\n",);

很明显,这里仍然会产生编译错误(非本例的某些情况下不会产生编译错误)。除了这种方式外,c99GNUCPP都支持下面的宏定义方式:

#definemyprintf(templt,...)fprintf(stderr,templt,##__VAR_ARGS__)

这时,##这个连接符号充当的作用就是当__VAR_ARGS__为空的时候,消除前面的那个逗号。那么此时的翻译过程如下:

myprintf(templt);

被转化为:

fprintf(stderr,templt);

这样如果templt合法,将不会产生编译错误。这里列出了一些宏使用中容易出错的地方,以及合适的使用方式。

Problem29 how to ignore an access violation exception in VC?

ANS:

__try

{

//code

}

__except(GetExceptionCode()==EXCEPTION_ACCESS_VIOLATION?

EXCEPTION_EXECUTE_HANDLER:

EXCEPTION_CONTINUE_SEARCH)

{

//donothing

}

抱歉!评论已关闭.