演讲嘉宾:到目前为止,它可能 大多数的程序 已经有点短暂。 你运行像马里奥或贪婪的程序。 它做的东西,它可能提示 对于某些信息的用户, 打印某些输出到屏幕上, 但是当你的程序已经结束了, 真的没有证据表明有 这是有史以来第一位执行。 我的意思是,当然,你可能已经离开 它在终端窗口中打开, 但如果你清楚你的屏幕上,有 真的没有证据证明它的存在。 我们没有存储的手段 持久性信息,信息 我们以后存在 程序已停止运行, 或者我们还没有到这一点。 幸运的是,虽然,C做 我们提供的能力 通过实施这样做 叫什么 一个文件,这样的结构,基本上 代表你会加倍文件 单击您的计算机上,如果你 用于图形用户环境。 一般工作时 与C,我们实际上 将要与工作 指针files--文件stars-- 除了一点点 当我们谈论的一对夫妇 的函数 使用文件指针工作。 你并不需要真的挖到 太深入的了解指针 自己。 有一点蝇头位 在这里,我们将谈论他们, 但一般文件指针和 三分球,而相互关联的, 不完全一样的东西。 现在,这是什么意思时, 我说的持久性数据? 什么是持久性数据? 我们为什么要关心它? 说,例如,该 你正在运行的程序 或者你已经重写一个 程序,这是一个游戏, 你想跟踪 所有用户的招式 因此,也许如果出了问题, 您可以查看在比赛结束后的文件。 这就是我们的时候,我们的意思是 谈论持久性数据。 在运行的过程中你 程序,文件被创建。 而当你的程序 已停止运行, 该文件仍然存在你的系统上。 我们可以看一下它,研究它。 并且使得节目将被设置为 创造了一些持久性数据, 程序后的数据存在 已完成运行。 现在,所有这些功能的工作 与创建文件和操作 他们以不同的方式 住在标准io.h, 这是一个头文件 你可能是英镑 包括漂亮的顶部 多所有程序 因为它包含的所述一个 对我们来说最有用的功能, printf的,这也让 住在标准io.h. 所以,你不需要砸向包括 任何其他文件可能 为了与文件指针一起工作。 现在,每一个文件的指针功能, 或者每一个文件I / O输入输出 功能,接收为一体 其参数或输入 文件pointer--除 一,FOPEN,这 是你用什么来获取文件 指针摆在首位。 但是,你打开后, 文件并且得到文件指针, 那么你可以将它们作为 参数的各种功能 我们要谈 今天,以及许多其他 这样您就可以使用文件。 因此,有6个漂亮 常见的基本要点 那我们要谈论今天。 FOPEN和它的同伴 函数fclose函数,龟etc 及其配套功能的fputc, 和FREAD及其配套功能, FWRITE。 因此,让我们马上进去。 fopen--它有什么作用? 那么,它会打开一个文件,并将其 给你一个文件指针指向它, 这样你就可以使用 文件指针作为参数 任何其他文件I / O功能。 最重要的事情 要记住的fopen 是,你必须开后 文件或在这里取得像一个呼叫, 你需要检查,以确保 那你回来的指针 不等于空。 如果你还没有看过上的视频 三分球,这可能没有什么意义。 但是,如果你尝试取消引用 一个空指针召回, 你的程序可能会吃亏 分段[听不清]。 我们要确保我们 得到了一个合法的指针返回。 的大多数时间我们将 已经获得了合法的指针回 它不会成为一个问题。 那么,我们如何拨打电话给fopen? 它看起来非常像这样。 文件明星ptr-- PTR是一个通用的 命名文件pointer-- FOPEN 我们通过在两件事情,一个文件名 和操作我们要进行。 所以,我们可能有一个电话,看起来像 this--文件明星PTR 1等于FOPEN FILE1.TXT。 而我所选择的操作为r。 那么,你认为r是在这里吗? 什么是各种各样的事情,我们 也许能够做的文件吗? 以r是操作,我们 选择当我们要读取文件。 所以我们基本上是在 我们做这样的呼吁 越来越自己一个文件指针 这样,我们便可以读取信息 从FILE1.TXT。 同样,我们可以打开的文件2.txt 写作,所以我们可以通过PTR2, 我在这里创建的文件指针, 作为参数传递给任何函数 将信息写入到一个文件。 而类似的写作,有 还可以选择追加一个。 之间的差 写作和附加 是当你写一个文件, 如果你打个电话给fopen写作 而该文件已经存在,它的 要覆盖整个文件。 这将启动 在开始的时候, 删除所有信息 这是已经存在。 然而,如果你打开​​它进行追加, 将进入该文件的结束 如果有已经在文本 它或在它的信息, 它将再启动 从那里写作。 所以,你不会丢失任何的 你以前做过的信息。 无论你想要写或追加 那种视情况而定。 但是,你可能知道的 正确的操作是在时机成熟时。 所以这是FOPEN。 什么fclose函数? 嗯,倒也干脆,fclose函数 刚刚接受文件指针。 正如你所期望的, 它将关闭该文件。 一旦我们已经关闭的文件,我们不能 执行任何更多的文件I / O功能, 读取或写入,在该文件中。 我们不得不重新打开 文件中的另一个时间,以便 继续与工作 使用它的I / O功能。 我们这样做fclose函数方法 正与此文件。 而所有我们需要传递的是 一个文件指针的名称。 因此,一对夫妇幻灯片前,我们 fopened文件1点文本阅读 我们分配了 文件指针ptr1的。 现在我们已经决定我们 完成从文件中读取。 我们不需要做任何更多的它。 我们可以只fclose函数ptr1的。 同样,我们能否 F关闭其他的。 好吧。 这样的开始和结束。 这些是两个基本 启动操作。 现在,我们要以实际 做一些有趣的东西, 和第一个功能,我们将 看到将这样做是fgetc-- 文件中获取一个字符。 这就是通常龟etc 将转化。 其人生目标是 读取下一个字符, 如果这是你很 到龟etc第一个电话 为一个特定的文件, 第一个字符。 但在那之后, 你的下一个, 该文件的最下一个字符, 并将其存储在一个字符变量。 正如我们所做的, 焦炭CH等于龟etc, 通过在一个文件指针的名称。 再次,这是非常 重要的是必须记住 是,为了有 这种操作成功, 文件指针本身意有所指 打开阅读。 我们不能从文件中读取一个字符 指针,我们进行写入操作。 所以这是之一 的FOPEN的限制,对不对? 我们一定要限制 我们只执行 一个操作一个文件指针。 如果我们想读, 从同一个文件中写入, 我们就必须打开两个独立的 文件指向同一file-- 一个用于读,一个用于写。 如此反复,唯一的理由 我提起这件事,现在是 因为如果我们要拨打电话 到龟etc,该文件指针意有所指 打开阅读。 然后倒也干脆, 所有我们需要做的 是通过在文件指针的名称。 因此,焦炭CH等于龟etc ptr1的。 那将让我们 接下来character-- 或再次,如果这是第一个 一次,我们已经取得了这一呼吁, 的第一character--任何 文件由ptr1的指向。 回想一下,这是文件1点文字。 它会得到的第一个字符 我们将其存储在变量通道。 很简单。 因此,我们只看到三个 功能和已经我们 可以做一些漂亮整洁。 因此,如果我们把这种能力 得到一个字符的 我们循环它 - 所以我们 继续得到字符 从一个文件过来, 过去,over--现在我们 可以读取每一个 字符的文件名。 如果我们打印的每一个字符 之后我们读它, 我们现在已经从文件中读取和 印刷的内容到屏幕上。 我们已经有效地连接起来 在屏幕上该文件。 而这正是 Linux命令的猫一样。 如果您在文件名中键入的猫,它 将打印出的全部内容 在终端窗口中的文件。 所以这里这个小环, 只有三行代码, 但它有效地复制 Linux命令猫。 所以这个语法可能 看起来有点怪异, 但这里的这里发生了什么。 虽然CH等于龟etc,ptr不 等于EOF--它是一个整体一口, 但让我们把它分解只 所以很明显的语法。 我已经巩固了它 为求空间, 虽然这是一个有点 语法棘手。 因此,这部分绿色右 现在,它在干什么? 好吧,这只是我们的龟etc电话,对不对? 我们已经看到过。 它获得一种 字符从该文件。 然后,我们比较一下 性格对EOF。 EOF是一个特殊的值,它是 在标准io.h,定义了 为文件结束字符。 所以基本上什么事情要发生 在这个循环将读取一个字符, 把它比作EOF时, 文件结束符。 如果它们不匹配,所以我们没有 到达文件的结尾, 我们将打印字符的。 然后,我们将回到 重新开始循环。 我们会得到一个字符,检查 对EOF,打印出来,等 等等, 以这种方式遍历 直到我们到达了文件的末尾。 然后由这一点, 我们将印 出文件的全部内容。 所以,再一次,我们只看到 FOPEN和fclose和龟etc 而且我们已经可以复制 Linux终端命令。 正如我在开始时说, 我们有龟etc和的fputc, 和的fputc是伴侣 和函数fgetc的。 所以,如你所想, 它是写入等效。 它可以让我们写一个 单个字符到一个文件。 同样,需要注意的是,刚 就像是与龟etc,该文件 我们正在编写到一定发生了 打开写入或追加。 如果我们尝试使用的fputc上的文件 我们已经为读而打开, 我们要吃亏 有点错误。 但通话是非常简单的。 的fputc大写的A PTR2,所有 这是怎么回事要做的就是它的 打算写的信 成阿成的文件2点 文本,这是的名称 文件我们打开并分配 指针PTR2。 所以,我们要编写一个 大写字母A到文件2点文字。 我们将编写一个感叹号 指向文件3点 文本,这是由ptr3指出。 如此反复,很简单在这里。 但是现在我们可以做的另一件事。 我们有这样的例子 我们只是在看 对能够复制猫 Linux命令,打印出一 到屏幕上。 好了,现在我们有能力 以从文件中读取字符 和写入字符的文件, 为什么我们不只是替换了 调用printf一个调用的fputc。 现在,我们已经重复CP, 一个非常基本的Linux命令 我们刚才谈到的方式长 以前在Linux命令的视频。 我们有效地已经 重复的就在这里。 我们读一个字符,然后我们 写这个角色到另一个文件。 从一个文件读,写 到另一个,遍地 一遍又一遍,直到我们遇到EOF。 我们一定要的到底 文件我们试图从复制。 而由我们自己编写的所有 的字符,我们需要将文件 我们正在写。 因此,这是CP,Linux的复制命令。 在一开始 这个视频,我的告诫 我们会聊 关于指针点点。 下面是具体在哪里我们 要谈论的指针 除了文件指针。 所以这个功能看起来有种可怕的。 它有几个参数。 有很多怎么回事。 有很多的不同 颜色和文字。 但实际上,它只是 龟etc通用版 这使我们能够得到任何 的信息量。 它可以是一个有点低效率的,如果我们是 获得的字符之一的时间, 通过文件迭代 一个字符的时间。 那岂不是更好得到 100在一个时间或500的时间? 那么,FREAD和它的伴侣函数 FWRITE,我们将谈谈 在第二,使我们能够做到这一点。 我们可以读取任意数量 从文件中的信息 我们存储在某个地方暂时的。 而不是能够只 在一个变量适合它, 我们可能需要将其存放在数组中。 因此,我们通过在四个 参数fread--指针 到我们的位置 要存储的信息, 多大每个信息单元 将成为信息多少个单位 我们想要收购,而从 我们希望得到他们的文件。 也许最好的说明 在这里的一个例子。 因此,让我们说,我们声明 10整数数组。 我们在刚刚宣布 堆栈任意诠释ARR 10。 所以这是非常简单的。 现在我们正在做的虽然是什么 frecall是我们在阅读为int的大小 次10字节的信息。 INT存在尺寸four--那 在C的整数的大小。 因此,我们正在做的事情是,我们正在阅读 40个字节的信息 从文件指向PTR。 我们要存储这些 40个字节的地方 在这里,我们已预留 40个字节的内存。 幸运的是,我们已经完成了由 声明ARR,该数组就在这里。 是能够保持的 10四字节单元。 因此,在总,它可以容纳40 个字节的信息。 而我们现在正在读40个字节 从文件的信息, 我们正在将它存储在编曲。 从指针的视频回忆 的阵列,如改编的名称, 真的只是一个指针 其第一元件。 所以,当我们通过在编曲那里,我们 是的,其实,传递一个指针。 同样,我们可以做的this-- 我们不一定 需要保存我们的缓冲区在堆栈中。 我们还可以动态地分配 一个缓冲区就是这样,用malloc。 请记住,当我们 动态分配内存, 我们将其保存在 堆,而不是叠。 但它仍然是一个缓冲区。 它仍然在这种情况下,是 保持640个字节的信息 因为双占用了八个字节。 而且我们要求为80人。 我们希望能有空间 持有80双打。 因此,80倍8是640个字节的信息。 这调用fread是 收集640个字节的信息 从文件指向 PTR现在将它存储在ARR2。 现在,我们也可以把FREAD 就像调用龟etc。 在这种情况下,我们只是想 从文件中获取一个字符。 我们不需要 数组来保存一个字符。 我们只需将其存放在 一个字符变量。 美中不足的,不过,是 当我们只是有一个变量, 我们需要传递的 该变量的地址 因为回想一下, 第一个参数FREAD 是指向的位置和存储器 在这里我们要存储的信息。 再次,一个名 阵列是一个指针。 所以我们并不需要做符号阵列。 但是,C,字符c 这里,不是数组。 这只是一个变量。 因此,我们需要传递一个 符号C到指示 那这就是我们想要的地址 存储信息的这一个字节, 这一个字符 我们收集的PTR。 Fwrite--我会去通过 这一点 quickly--几乎是 FREAD的完全等效 除了它的写作 而不是阅读,只是 像other--我们已经开 和关闭,进入一个人物, 写一个字。 现在,获得任意 的信息量, 右的任意数量的信息。 因此,只要像以前一样,我们可以 有10整数数组 在这里我们已经有 信息存储,也许吧。 这可能是一些代码行 应在这两者之间去 在这里我填写常用3与 有意义的事。 我填补它与10个不同的整数。 而相反,就是我 做的是从编曲写 和收集从ARR的信息。 我要带的资料 把球送入该文件。 因此,而不是其被 文件到缓冲器, 我们现在从去 缓冲区到该文件。 因此,它正好相反。 如此反复,就如同之前,我们就可以 也有一个内存堆块 我们动态地已经 分配并从阅读 并编写该文件。 而且我们也有一个变量 能够容纳一个字节 的信息,诸如字符。 但同样,我们需要传递 该变量的地址 当我们想从中读取。 因此,我们可以写信息 我们发现在该地址 该文件指针,PTR。 还有很多其他的 大文件I / O功能 即做各种事情,除了 那些我们已经谈到了今天。 一对夫妇的那些 你可能会发现有用 是fgets和的fputs, 它们是等效 的龟etc和的fputc但对于阅读 从文件中一个字符串。 而不是一个单一的字符, 它会读取整个字符串。 fprintf中,基本上允许 你用printf写入文件。 所以,就像你可以做 使用变量替换 占位符%的I和 百分之d和等,具有的printf 你同样可以把 printf的字符串和打印的东西 这样的一个文件。 fseek--如果你有一台DVD播放机 就是这个比喻我通常使用这里 - 有点像用你 快退和快进 按钮移动影片各地。 同样,您可以在文件移动。 一个里面的东西 该文件的结构 将c为您创建是一个指标 在那里你是在文件中。 你是在很 开始,在0字节? 你是在字节100, 字节1000,以此类推? 您可以使用fseek的任意移动 该指标前进或后退。 而FTELL,再次 类似于DVD播放机, 就像一个小时钟,告诉 你有多少分钟,你秒 是到特定的电影。 同样,FTELL告诉您如何 你是到文件的字节数。 的feof是一个不同的版本 检测你是否已经 到达文件的结尾。 和ferror是一个函数 您可以使用 检测到的东西是否有 出了问题的工作与文件。 同样,这仅仅是 表面文章。 仍然有很多更多的文件I / O 在标准io.h.功能 但是,这可能会得到你 开始与文件指针工作。 我是道格·劳埃德。 这是CS50。