gets、fgets、puts、fputs、scanf、read、readline、getline等

一、gets

gets是个不安全的函数,应该坚决不用。它每遇到换行符就会返回,即使是一开始就遇到一个换行符。返回后会将换行符变为'\0'。由于gets()无法知道字符串的大小,必须遇到换行字符或文件尾才会结束输入,因此容易造成缓存溢出的安全性问题。


二、fgets

char *fgets(char *buf, int bufsize, FILE *stream); 

当遇到换行符或者缓冲区已满,fgets就会停止,返回读到的数据。注意换行符会被保存在缓冲区中,只是后面再加个'\0'

注意,对于fgets来说,'\n'是一个特别的字符,而'\0'并无任何特别之处,如果读到'\0'就当作普通字符读入。如果文件中存在'\0'字符(或者0x00字节),调用fgets之后就无法判断缓冲区中的'\0'究竟是从文件读上来的字符还是由fgets自动添加的结束符,所以fgets只适合读文本文件而不适合读二进制文件,并且文本文件中的所有字符都应该是可见字符,不能有'\0'。


补充:glibc提供的getline函数:参考http://man7.org/linux/man-pages/man3/getline.3.html

可以读取不定长的“行”,能正确处理各种情况,但是它返回的是malloc分配的内存,需要用户自己free掉。

       #define _GNU_SOURCE
       #include <stdio.h>
       #include <stdlib.h>

       int
       main(void)
       {
           FILE *fp;
           char *line = NULL;
           size_t len = 0;
           ssize_t read;

           fp = fopen("/etc/motd", "r");
           if (fp == NULL)
               exit(EXIT_FAILURE);

           while ((read = getline(&line, &len, fp)) != -1) {
               printf("Retrieved line of length %zu :\n", read);
               printf("%s", line);
           }

           free(line);
           fclose(fp);
           exit(EXIT_SUCCESS);
       }

三、scanf

char str[100]; scanf("%s", str); 

如果scanf在开头遇到前次函数留下的空格或换行符,scanf一律跳过, 继续运行;如果在中间遇到空格或遇到换行符,scanf将会停止。在读取的字符串后加上'\0'。


四、puts与fputs

int puts(const char *string);

int fputs(const char *str, FILE *fp);  //注意区别于fputc(c, fin).

fputs向指定的文件写入一个字符串,puts向标准输出写入一个字符串。

缓冲区s中保存的是以'\0'结尾的字符串,fputs将该字符串写入文件stream,但并不写入结尾的'\0'。与fgets不同的是,fputs并不关心的字符串中的'\n'字符,字符串中可以有'\n'也可以没有'\n'。puts将字符串s写到标准输出(不包括结尾的'\0'),然后自动写一个' \n'到标准输出


五、read是一个系统调用,其他函数会调用该函数

ssize_t read(int filedes, void *buf, size_t nbytes); 从终端读可以char data[100]; n = read(STDIN_FILENO, data, 100);

 read 函数从 filedes 指定的已打开文件中读取 nbytes 字节到 buf 中。以下几种情况会导致读取到的字节数小于 nbytes :
    A. 读取普通文件时,读到文件末尾还不够 nbytes 字节。例如:如果文件只有 30 字节,而我们想读取 100 字节,那么实际读到的只有 30 字节,read 函数返回 30 。此时再使用 read 函数作用于这个文件会导致 read 返回 0 。
    B. 从终端设备(terminal device)读取时,一般情况下每次只能读取一行。
    C. 从网络读取时,网络缓存可能导致读取的字节数小于 nbytes 字节。
    D. 读取 pipe 或者 FIFO 时,pipe 或 FIFO 里的字节数可能小于 nbytes 。
    E. 从面向记录(record-oriented)的设备读取时,某些面向记录的设备(如磁带)每次最多只能返回一个记录。
    F. 在读取了部分数据时被信号中断。

注意:read不会自动加上'\0';对于\n,它也是原封不动的读入,当做普通字符


六、readline库

#include <readline/readline.h>
#include <readline/history.h>
char *line_read = (char *)NULL;
line_read = readline("Please Enter:");

readline 是一个强大的库,只要使用了它的程序,都可以用同一个配置文件配置,而且用同样的方法操作命令行,让你可以方便的编辑命令行。


七、strlen

返回字符串的长度。该字符串可能是自己定义的,也可能是内存中随机的,该函数实际完成的功能是从代表该字符串的第一个地址开始遍历,直到遇到结束符NULL。返回的长度大小不包括NULL。


八、C的关于打开、读取、关闭文件的api

std::string s;
FILE *fin=fopen("e:\\in.txt","r");
FILE *fout=fopen("e:\\out.txt","w");
while(fscanf(fin,"%c",&c)!=EOF)
{
	s+=c;
	fprintf(fout,"%s",s.c_str());
	fputc(c,fout);
}
fclose(fin);
fclose(fout);

九、C++部分

http://www.cnblogs.com/JCSU/articles/1190685.html

1、逐词读取, 词之间用空格区分

    ifstream fin("data.txt");  //#include <fstream>
    string s;                  //#include <string>
    while( fin >> s ) 
    {    
        cout << "Read from file: " << s << endl;  
    }
    fin.close(); //最后别忘了关闭

2、行读取, 将行读入字符数组, 行之间用回车换行区分

    ifstream fin("data.txt"); 
    const int LINE_LENGTH = 100; 
    char str[LINE_LENGTH];  
    while( fin.getline(str,LINE_LENGTH) )   //如果是终端,就是cin.getline(str, LINE_LENGTH)
    {                                       //默认遇到\n即结束读取,最多读取99个字符,并在结尾自动加\0.
        cout << "Read from file: " << str << endl;
    }

3、逐行读取, 将行读入字符串, 行之间用回车换行区分

    ifstream fin("data.txt");  
    string s;  
    while( getline(fin,s) )   //如果是终端,就是getline(cin, s)
    {                         //注意这里s必须是string,而不能是字符数组。s的末尾会自动有\0.
        cout << "Read from file: " << s << endl; 
    }

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值