1. C语言中,注意getline()和fgets()的区别,两者都是读取文件的一行。但是用法有所区别。
getline()的定义是
size_t getline(char ** s, size_t * n, FILE* fp);
该函数在调用的时候,不用为s分配内存,该函数内部会为其动态分配内存,如果调用成功,将返回分配内存的长度。碰到文件结尾则返回EOF,即-1. 例如
#include<stdio.h>
#include<malloc,h>
int main()
{
char * s = NULL;
size_t n;
FILE * fp = fopen("a.txt","r");
while(!feof(fp)){
size_t a = getline(&s,&n,&fp);
printf("%d,%s\n",a,s);
free(s);
s=NULL;
}
}
需要注意的是,将s初始化为NULL,每次读取完毕,释放s,再将其设定为NULL是不可缺少的,否则,这个函数不一定能运行成功。因为s可能指向一个不可访问的内存地址。会得到Segmentation fault (core dump)的错误。
fgets()的定义是
char * fgets(char * s, int n, FILE * fp);
s必须提前被分配内存,不管是动态分配,还是数组形式,n是读取长度的上限。成功时,返回buf,否则返回null. 用于接收返回值的字符型指针则不需要提前分配内存。
2. 注意C中getline 与 C++中get的区别
C++中getline主要有两种形式,一种是以输入流(istream, ifstream)的成员函数调用,一种是string类的成员函数调用。前者需要istream,ifstream,后者需要string
以输入流成员函数调用
istream & getline(char * s, int n) 或 istream & getline(char * s, int n, char c)
s必须事先分配内存,n是最长读取长度,c是指示读取终止的字符,前者,并不读取换行符。后者也不读取控制字符c。
以string成员函数调用
istream & getline(istream & istr, string & s) 或 istream & getline(istream & istr, string & s, char c)
s定义时可以使用string的默认构造函数,即string s; 同样这两个函数也不读取还行符或者控制字符c。
3. 文件重新定位后需要注意的问题
在C语言里面,文件读到文件末尾之后,用fseek()函数可以直接重新定位,并且继续读取。然而在C++里面,用文件输入流成员函数seekg()来重新定位,不一定能继续读取。这取决于前一次的读取是否遇到了文件末尾,如果遇到了,必须在seekg()之前,先调用文件输入流成员函数clear()。