C编程基础day12

\r 是每次输出都在最左端。

fflush(stdout); 因为打印的时候不会立即放在屏幕,而是先放在内存,再放到缓存区等到缓存区满了的时候才放在屏幕。调用这个函数后即便缓存区没满也会将printf的内容显示到屏幕上。 使用缓存区是为了提高效率,避免太频繁地从内存往屏幕写东西,而是先把要显示的东西存到缓存区,等攒够了再给屏幕。 读取缓存区类似。

文件指针:FILE *fp;  //

所有平台的FILE名字都一样,FILE是一个结构体类型,里面成员的功能一样, 但是不同平台的结构体成员名字不一样。

fp指针只要调用了fopen()函数,就会在堆区分配空间,然后将地址返回fp.

fp指针不是指向文件,fp指针和文件关联,fp内部成员保存了文件状态。  fp不是指向文件(文件在磁盘呢,没法指),所以*fp不是文件的内容. 别想通过*fp看文件内容。

fp和文件关联的方法是给文件分一个文件描述符,这个文件描述符石FILE结构体的一个成员。

操作fp指针,不能直接操作,必须通过库函数来操作fp指针。 所以别想使用fp++或者*fp等操作。

通过库函数操作指针,对文件的任何操作,fp指针的指向的结构体内部成员都会有相应的变化(系统自动完成)。

文件分为设备文件和磁盘文件

磁盘文件:通常存储在外部介质(磁盘)上,使用时才调入内存。

设备文件:屏幕、键盘等与主机相连的设备...把对他们的输入输出等同于对磁盘文件的输入输出。stdout, stdin。

磁盘文件又分为文本文件和二进制文件

文本文件:基于字符编码的文件。常见有ASCII 和UNICODE等,一般可用文本编辑器打开。

二进制文件:基于值编码的文件。

文件操作实际上就3步骤。 

1、打开文件fopen()

2、读写文件

     2.1按字符读写fgetc()  fputc()

     2.2按字符串(行)读写fgets() fputs()

     2.3文件结尾的判断feof()

3、关闭文件fclose()

printf("aaaaaa\n");//可以打印

fclose(stdout);  //关闭标准输出

printf("bbbbbb\n");//没有打印出来,因为前一语句关闭了标准输出。

perror("Mike");//打印库函数调用失败的原因,函数参数必须是字符串。

fclose(stderr); //关闭输出标准出错信息

perror("Wang");//无法打印,因为前一语句关闭了标准出粗。

int a =10;

fclose(stdin);//关闭标准输入

scanf("%d",&a);//直接跳过这一步,无法输入a的值,以为内前一语句关闭了标准输入。

printf("a=%d\n",a);

若想使用printf往磁盘文件中写东西,要把标准输出先关了,因为printf默认往标准输出(1)中写内容。

printf("Before aaaaaa\n");//printf函数的内部实现往标准输出(1)中写内容

close(1); // 使用close而不是fclose是以为内close是系统调用,属于操作系统接口。

int fd = open("01.txt",O_WRONLY,0777); // 使用open不是fopen, 返回值是返回最小可用的文件描述值,所以返回1.

printf("fd =%d\n",fd); //在文件中显示返回值fd为1

printf("After aaaaaaa\n");//在文件中显示

windows下路径写法,两个反斜杠\\因为反斜杠是转义字符

fp = fopen("D:\\新建文件夹\\a.txt","w");

windows和linux都可用以下的形式

fp = fopen("D:/新建文件夹/a.txt","w");

当前路径:

fp = fopen("a.txt","w");

fp = fopen("./a.txt","w");

相对路径

fp = fopen("/home/edu/a.txt","w");

fopen会在堆区分配空间,返回地址给fp。fp指向FILE结构体。

相对路径:

在linux环境下,相对路径是指相对于可执行可执行程序。

在VS环境下,

    a.编译同时运行程序,相对路径是相对于XXX.vcxproj所在路径。

    b.直接运行exe程序,相对路径是相对于可执行程序。

在QT环境下,

    a.编译同时运行程序,相对路径是相对于debug所在路径。

    b.直接运行exe程序,相对路径是相对于可执行程序。

以下4种情况等价

fopen("1.txt","w");

char *p = “1.txt”;

fopen(p,"w"); //p指向字符串首元素地址

char p[] = “1.txt”;

fopen(p,"w");//传递时是字符串首元素地址

char *mode = “1.txt”;

fopen("1.txt",mode);

fputc每次写一个字符到某个字符, putc和putc功能完全一样,但是putc是宏定义不是真正地函数调用。

fgetc从某个文件读取一个字符,每读取一次光标向右移一次。

1、如果是文本文件可以通过-1(EOF)来判断是否文件结尾。

2、如果是二进制文件就 不能通过-1判断文件结尾,因为二进制文件中可能有很多-1。

3、feof()判断文件是否结尾,任何文件都能判断。  feof是根据fp的文件信息判断的,不是根据文件内容返回值判断的。

feof(fp)文件结尾时返回TRUE.

1、如果第一次没有对文件进行读操作,直接调用此函数,永远返回假(代表文件没有到结尾)。这里的读操作指的是fgetc等读操作。

2、feof()函数必须先读,再调用feof(),才有意义。 因为不读的话,相当于没有开始呢,怎么判断结束。

3、调用此函数,光标不会自动往后移动。  读操作后光标才能往后移。

4、读取后才能判断是否结束,判断的是已读取的那个字符。

使用feof函数判断结束的时候会读取最后标志结尾的那个-1,所以显示读取内容的时候最好在if(foef(fp))break;之后再显示读取内容。

int main(int argc,char *argv[])该函数中int argc和argv[]两个参数的理解你懂多少?

说明一下:argc命令行总的参数的个数,即argv中元素的格式。

* argv[ ]: 字符串数组,用来存放指向你的字符串参数的指针数组,每一个元素指向一个参数

argv[0]:指向程序的全路径名

argv[1]:指向在DOS命令行中执行程序名后的第一个字符串。

argv[2]:指向第二个字符串。

举例子执行程序   ./a.out 01.txt    中argv[0]是./a.out   argv[1]是01.txt

自己用C语言实现vi操作代码如下所示。

   

fputs

fgets函数读取,遇到换行符、文件结尾、出错时候,结束本次读取。

char buf[100];

fgets(buf, sizeof(buf), fp);

为了避免读取失败的时候buf仍能打印buf中存储的上次读取的值,最好每次使用fgets函数之前先清空buf。

memset(buf, 0,sizeof(buf));

fgets(buf, sizeof(buf), fp);

函数可改动如下:

while(1)

{

    fgets(buf,sizeof(buf),fp);//从fp往buf中读内容,最多读sizeof(buf)-1个。默认读取到换行符\n或者文件结尾,或者出错,才结束本次读取。

    if(feof(fp)) //如果读取失败,直接跳出。

    {

         break;

    }

    printf("buf = %s",buf);//读取成功则打印。

}

VS调试中鼠标点中某个宏按F12可以看它定义的地方。

猜你喜欢

转载自blog.csdn.net/Shayne_Lee/article/details/81436145