scanf()函数用法示例

最近详细看了一下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
*/


 

注意几个地方:

  1.  留足缓冲区。为fscanf()指定的缓冲区,末端要额外保留至少一个字节,因为fscanf()可能会填充null字符。
  2.  "%80[^\r\n]%c"的含义是:读入不是'\r'和'\n'的字符,一直读取到出现'\r'或'\n'(但是将'\r'和'\n'留作下次读取),然后再读取一个字符(这个字符必然是'\r'或'\n'之一)。还有一种情况是:读入不是'\r'和'\n'的字符,直到读满了80个字符,然后再读取一个字符。符号%[...]是读取'['和']'之间的模式,而^符号是逻辑取反。
  3. "%*c",含义是:读取一个字符,但是不作任何处理,抛弃之。注意有个星号。
  4. 不同的平台对换行有不同的处理,具体来说,windows是用'\r\n',linux用'\n',mac用'\r'。本示例用二进制方式打开文本文件。
  5. fscanf()返回值为0,可能是因为遇到了'\r\n'中的'\n',也可能是遇到了空行。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值