最新消息:热烈庆祝IT小记上线!

C笔记-文件读写

  从文件编码的方式来看,文件可分为ASCII码文件和二进制码文件两种。
  ASCII文件也称为文本文件,这种文件在磁盘中存放时每个字符对应一个字节,用于存放对应的ASCII码。例如,数5678的存储形式为:
ASC码: 00110101 00110110 00110111 00111000
     ↓     ↓    ↓    ↓
十进制码: 5     6    7    8 共占用4个字节。ASCII码文件可在屏幕上按字符显示, 例如源程序文件就是ASCII文件,用DOS命令TYPE可显示文件的内容。 由于是按字符显示,因此能读懂文件内容。

  二进制文件是按二进制的编码方式来存放文件的。 例如, 数5678的存储形式为: 00010110 00101110只占二个字节。二进制文件虽然也可在屏幕上显示,但其内容无法读懂。C系统在处理这些文件时,并不区分类型,都看成是字符流,按字节进行处理。输入输出字符流的开始和结束只由程序控制而不受物理符号(如回车符)的控制。 因此也把这种文件称作“流式文件”。

  因此,文件的打开方式也分为以文本方式和二进制方式打开:   
  举个例子,一个32位数字0x0000200十进制数512,可以以两种方式存在文件中。第一种是人易读的方式"512",存储3个 字符,每个字符按ASCII码存放,这样用一个文本编辑器打开,人可以容易的读到这个数是512。 第二种方式是以机器易读的方式直接存储4个字节一个32位的00 00 02 00,这样机器容易读取这个数是512,直接内存拷贝就可以。 否则机器就要首先将"512"读每一个字符, 然后将"5"这个字符的ASCII码转换成5, 最后执行一个5*100+1*10+2才能得到512这个数。fwrite和fread都是机器易读的方式。 从文件中将00 00 02 00读入一个int类型变量,用fread写就是
  fread(&a, sizeof(int), 1, fp);
  即从文件中读取一个大小为sizeof(int)的内容到内存地址&a。
  相应的fwrite形式是
  fwrite(&a, sizeof(int), 1, fp);
  若文件中存储的是人易读的形式比如 “512 ”,那么要处理就最好使用fscanf和fprintf。

  对于fgetc函数的使用有以下几点说明:
1. 在fgetc函数调用中,读取的文件必须是以读或读写方式打开的。


2. 读取字符的结果也可以不向字符变量赋值,例如:fgetc(fp);但是读出的字符不能保存。


3. 在文件内部有一个位置指针。用来指向文件的当前读写字节。在文件打开时,该指针总是指向文件的第一个字节。使用fgetc 函数后,该位置指针将向后移动一个字节。 因此可连续多次使用fgetc函数,读取多个字符。应注意文件指针和文件内部的位置指针不是一回事。文件指针是指向整个文件的,须在程序中定义说明,只要不重新赋值,文件指针的值是不变的。文件内部的位置指针用以指示文件内部的当前读写位置,每读写一次,该指针均向后移动,它不需在程序中定义说明,而是由系统自动设置的。

用fopen打开一个文本文件,fopen的第一个参数为文件路和文件名,第二个参数定义的是打开文件的方式,执行完fopen后,需要判断一下,此文件是否确实被打开了。
if(NULL == fd)printf("文件未被打开");
接下来就可以进行文件的操作了。
读文件的函数有好几个,fread,fscanf,fgets。它们之间是有区别的:
fread是以块的方式来读取数据,按照指定的长度和指定的次数来读,读完后的数据是按照地址的方式来存储的,所以,比较适合用它来读二进制数,因为程序员比较清楚的知道自己要读多少的数据。
fgets是以串的方式来读取数据,从数据文件中读取不超过N-1个字符的数,读入的数据在最后一个字符后会加上一个截止符'\n',如果中间出现了回车,就会截止了。所以可以用fgets来读入一行的文本数据,应该是相当好用的。
fscanf与fgets类似,不过它是按照格式来读的,跟scanf一样。比如说,指定一个%d,那么它就读入一个整型的值;如果指定一个%s,那么它遇到一个空格也会停止的。
以下是一个实际的代码,用三种方式来完成文件的读取。

#include <stdio.h> 
int main()
{
    FILE *fd;
    char buf[64];
    fd = fopen("txtfile.txt","rb");
    if(NULL == fd)
    {
      printf("read file error!");
      return 0;       
    }
    printf("read file success!\n");
    while(!feof(fd))
    {
        /*method 1
      fgets(buf,64,fd);
      printf("%s\n",buf);
      */
      /*method 2
      fread(buf,64,1,fd);
      printf("the %dth time: %s \n ",count,buf);
      */
      fscanf(fd,"%s",buf);
      printf("%s\n",buf);
    }   
    fclose(fd);
    return 1;
}
 
<span style="font-size:18px;">标准C++ 读文件内容</span>
<pre name="code" class="cpp">//标准C++ 读文件内容  ( 仿PHP ) 2012-8-12 by Dewei
//用法:string s = file_get_contents("C:\\LICENSE.txt"); 
string file_get_contents(const string &filename)  
{  
	string contents = "";
	fstream in;
	in.open(filename.c_str(), fstream::in|fstream::binary|fstream::ate);
	if (in.good()) {  
		fstream::pos_type end_pos = in.tellg();
		long num_size = end_pos; 
		++num_size;
		in.seekg (0, fstream::beg);  
		char *buffer = new char[num_size];
		memset(buffer, 0, num_size);
		in.read(buffer, end_pos);  
		in.close();  
		contents = buffer;
		if (buffer != NULL)
			delete[] buffer;
	}
	return contents;  
}  

//标准C++ 写入文件内容 ( 仿PHP )  2012-8-12 by Dewei
//用法:file_put_contents("C:\\LICENSE.txt", "写入内容");
bool file_put_contents(const string &filename, const string contents)
{
	fstream out;
	out.open(filename.c_str(), fstream::out|fstream::binary);
	if (out.good()) {
		out.write(contents.c_str(), contents.length());
		out.close();
	}
	return true;
}

C 语言实现 读取文件内容

<pre name="code" class="cpp">//C 语言实现 读取文件内容 ( 仿PHP ) 2012-6-25 by Dewei
//用法:string s = file_get_contents("C:\\LICENSE.txt");
string file_get_contents(const string &filename)  
{  
	string contents;  
	FILE *fp;  
	fp = fopen(filename.c_str() , "rb");  
	if (fp == NULL) {  
		return "";  
	}  
	fseek(fp, 0, SEEK_END);  

	int file_size = ftell(fp);  

	char *tmp;  
	fseek(fp, 0, SEEK_SET);  
	tmp =  (char *)malloc(file_size+1);  
	memset(tmp, 0, file_size+1);  
	fread(tmp, sizeof(char), file_size, fp);  
	if (ferror(fp)) {  
		/* now, it is an error on fp */   
	}  
	fclose(fp);  
	contents = tmp;  
	free(tmp);  
	return contents;  
}  

//C 语言实现 写入文件内容 ( 仿PHP ) 2012-6-25 by Dewei
//用法:file_put_contents("C:\\LICENSE.txt", "写入内容");
bool file_put_contents(const string &filename, const string contents)
{
	FILE *fp;
	fp = fopen(filename.c_str() , "wb");
	if (fp == NULL) {
		return false;
	}
	fwrite(contents.c_str(), contents.length(), 1, fp);
	fclose(fp);
	return true;
}

 

c_str函数讲解

c_str函数的返回值是const char*的,不能直接赋值给char*,所以就需要我们进行相应的操作转化,下面就是这一转化过程。
c++语言提供了两种字符串实现,其中较原始的一种只是字符串的c语言实现。与C语言的其他部分一样,它在c++的所有实现中可用,我们将这种实现提供的字符串对象,归为c-串,每个c-串char*类型的。
  标准
头文件<cstring>包含操作c-串的函数库。这些库函数表达了我们希望使用的几乎每种字符串操作。 当调用库函数,客户程序提供的是string类型参数,而库函数内部实现用的是c-串,因此需要将string对象,转化为char*对象,而c_str()提供了这样一种方法,它返回const char*类型(可读不可改)的指向字符数组指针。 例
  

#include <iostream>
  #include <string>
  using namespace std;
  int main()
  {
  string add_to = "hello!";
  const string add_on = "baby";
  const char *cfirst = add_to.c_str();
  const char *csecond = add_on.c_str(); 
  char *copy = new char[strlen(cfirst) + strlen(csecond) + 1];
  strcpy(copy, cfirst);
  strcat(copy, csecond);
  add_to = copy;
  cout << "copy: " << copy << endl;
  delete [] copy;
  cout << "add_to: " << add_to << endl;


  //我强烈建议,以及我的老师也强烈建议我
  //一定要用return 0; 来告诉系统:程序正常结束.
  //return -1;是用来告诉系统:程序异常结束
  //亲们,做开发要认真~共勉~
  //一定要用 int main()
  return 0;
  }
  //以上程序过编译
  //VC 6.0, win7, - -!兼容性差
  ——————
  简单的例子: 
  函数声明:const char *c_str();
  c_str()函数返回一个指向正规C字符串的指针, 内容与本string串相同. 
  这是为了与c语言兼容,在c语言中没有string类型,故必须通string类对象成员函数c_str()把string 对象转换成c中的字符串样式。
  注意:一定要使用strcpy()函数 等来操作方法c_str()返回的指针 
  比如:最好不要这样: 
  char* c; 
  string s="1234"; 
  c = s.c_str();
  //c最后指向的内容是垃圾,因为s对象被析构,其内容被处理(纠正:s对象的析构是在对指针c完成赋值操作之后进行的,故此处并没有错误)
  在vc++2010中提示的错误原因:
  应该这样用: 
  char c[20]; 
  string s="1234"; 
  strcpy(c,s.c_str()); 
  这样才不会出错,c_str()返回的是一个临时指针,不能对其进行操作
  ———再举个例子———
  c_str() 以const char* 类型返回 string 内含的字符串
  如果一个函数要求char*参数,可以使用c_str()方法: 
  string s = "Hello World!";
  printf("%s", s.c_str()); //输出 "Hello World!" 
  ——————
  c_str在打开文件时的用处:
  当需要打开一个由用户自己输入文件名的文件时,可以这样写:ifstream in(st.c_str());。其中st是string类型,存放的即为用户输入的文件名。


   
                
                

猜您喜欢

备案号:苏ICP备12016861号-4