您的位置:首页 > 其它

scanf()函数用法示例

2011-07-20 21:19 756 查看
最近详细看了一下scanf()函数的用法,发现比printf()要复杂。这里演示scanf()函数族的用法。以fscanf()为例,按行扫描文本文件,并逐行打印。

/*  test_scanf.c
*
*    scanf() fscanf() 使用示例。
*    按行扫描 ascii 文本文件,忽略空行(仅含回车/换行符的行)。
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BUFFER_SIZE 20

int main(int argc,char* argv[])
{
char line[BUFFER_SIZE+1];
char cmd[80]; /* const */
int i = 0;
FILE* fp;
int ret;
char c1;

fp = fopen("test.txt","rb");
if(!fp) {
perror("test.txt");
exit(-1);
}
fseek(fp, 0L, SEEK_SET);

/* e.g. "%80[^\r\n]%c" */
sprintf(cmd,"%%%d[^\r\n]%%c", BUFFER_SIZE);

printf("[");

while(1) {
c1='\0';
ret = fscanf(fp, cmd, line, &c1);
if(ret==EOF)
break;
else if(ret==0) { /* eat another '\r' or '\n'. e.g. '\r\n' for DOS. */
ret = fscanf(fp, "%*c");
continue;
}

for(i=0; i<BUFFER_SIZE; i++) {
if(line[i]=='\0')
break;
printf("%c",line[i]);
}

if(c1 == '\n' || c1 == '\r')
printf("]\n[");
else  /* incomplete line */
fseek(fp, -1L, SEEK_CUR); /* repeat it */
}

printf("\n");
fclose(fp);
return 0;
}
/**
gcc -Wall test_scanf.c
*/


注意几个地方:
留足缓冲区。为fscanf()指定的缓冲区,末端要额外保留至少一个字节,因为fscanf()可能会填充null字符。
"%80[^\r\n]%c"的含义是:读入不是'\r'和'\n'的字符,一直读取到出现'\r'或'\n'(但是将'\r'和'\n'留作下次读取),然后再读取一个字符(这个字符必然是'\r'或'\n'之一)。还有一种情况是:读入不是'\r'和'\n'的字符,直到读满了80个字符,然后再读取一个字符。符号%[...]是读取'['和']'之间的模式,而^符号是逻辑取反。
"%*c",含义是:读取一个字符,但是不作任何处理,抛弃之。注意有个星号。
不同的平台对换行有不同的处理,具体来说,windows是用'\r\n',linux用'\n',mac用'\r'。本示例用二进制方式打开文本文件。
fscanf()返回值为0,可能是因为遇到了'\r\n'中的'\n',也可能是遇到了空行。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: