1 00:00:00,000 --> 00:00:02,700 [Powered by Google Translate] [演练 - 习题集4] 2 00:00:02,700 --> 00:00:05,000 [Zamyla陈 - 哈佛大学] 3 00:00:05,000 --> 00:00:07,340 [这是CS50。 - CS50.TV] 4 00:00:08,210 --> 00:00:11,670 好的。你好,大家好,欢迎来到演练4。 5 00:00:11,670 --> 00:00:14,270 >> 今天,我们的pset取证。 6 00:00:14,270 --> 00:00:18,080 取证是一个非常有趣的pset中涉及位图文件 7 00:00:18,080 --> 00:00:21,550 发现谁犯了罪。 8 00:00:21,550 --> 00:00:24,200 然后我们要改变某些位图文件, 9 00:00:24,200 --> 00:00:27,780 然后我们要处理一个真正有趣的部分称为恢复, 10 00:00:27,780 --> 00:00:31,160 我们基本上是交给一个记忆卡 11 00:00:31,160 --> 00:00:34,350 有人不小心删除他们的所有文件, 12 00:00:34,350 --> 00:00:38,860 我们要求恢复这些文件。 13 00:00:38,860 --> 00:00:42,910 >> 但是,首先,在我们进入的pset中,我真的只是想祝贺大家。 14 00:00:42,910 --> 00:00:45,230 我们在这门课程的中点。 15 00:00:45,230 --> 00:00:50,070 测验0是在我们的身后,我们在pset4,所以基本上,我们已经完成一半。 16 00:00:50,070 --> 00:00:55,490 我们已经走过了很长的路要走,如果你回头看看您的pset中,pset0和pset1移动, 17 00:00:55,490 --> 00:00:57,300 所以祝贺了解, 18 00:00:57,300 --> 00:01:00,760 我们会得到一些真正有趣的东西。 19 00:01:00,760 --> 00:01:07,070 >> 因此,我们的工具箱,这pset的,而不是运行sudo yum的-Y更新, 20 00:01:07,070 --> 00:01:13,890 我们可以只运行update50,如果你在17.3及以上版本的设备。 21 00:01:13,890 --> 00:01:17,380 所以一定要运行update50 - 这是一个容易得多,少一些字符 - 22 00:01:17,380 --> 00:01:20,640 以确保你在最新版本的设备。 23 00:01:20,640 --> 00:01:25,410 尤其重要的是update50当我们开始使用CS50检查。 24 00:01:25,410 --> 00:01:28,700 所以一定要确保你这样做。 25 00:01:28,700 --> 00:01:30,760 >> 对于所有此pset的部分, 26 00:01:30,760 --> 00:01:34,350 我们将要处理的文件的输入和输出,文件I / O。 27 00:01:34,350 --> 00:01:38,140 我们将要超过了很多的阵列处理的程序 28 00:01:38,140 --> 00:01:40,350 指向文件之类的东西, 29 00:01:40,350 --> 00:01:43,050 所以我们要确保我们是非常熟悉和舒适的 30 00:01:43,050 --> 00:01:47,990 处理与如何到文件中的输入和输出。 31 00:01:47,990 --> 00:01:52,080 >> 在分配的pset此代码是一个文件名为路径'%s', 32 00:01:52,080 --> 00:01:55,280 这就是我们要寻找的是要真正对我们有用的 33 00:01:55,280 --> 00:02:00,340 因为我们要结束了,其实复制copy.c文件 34 00:02:00,340 --> 00:02:05,350 ,只是略微改变,能够实现第2部分的问题集。 35 00:02:05,350 --> 00:02:09,030 >> 这样的话,正如我之前提到的,我们正在处理的位图,以及为JPEG格式。 36 00:02:09,030 --> 00:02:13,170 所以,真正了解这些文件是如何组织的结构, 37 00:02:13,170 --> 00:02:16,170 我们如何才能真正转化到结构的“0”和“1 38 00:02:16,170 --> 00:02:19,040 和活动,我们实际上可以理解,解释和修改, 39 00:02:19,040 --> 00:02:21,000 这将是非常重要的, 40 00:02:21,000 --> 00:02:25,970 进入JPEG和位图文件,并了解这些结构。 41 00:02:25,970 --> 00:02:30,780 >> Pset4,像往常一样,开始了部分问题。 42 00:02:30,780 --> 00:02:36,600 这些将处理文件I / O,让你习惯了。 43 00:02:36,600 --> 00:02:42,520 第1部分是谁是凶手,你给定一个位图文件 44 00:02:42,520 --> 00:02:45,630 看起来有点像所有的红点。 45 00:02:45,630 --> 00:02:52,180 然后基本上我们要做的是这个文件,只是稍微编辑 46 00:02:52,180 --> 00:02:54,010 到一个版本,我们可以阅读。 47 00:02:54,010 --> 00:02:56,000 从本质上讲,一旦我们完成,我们将具有相同的文件, 48 00:02:56,000 --> 00:03:02,630 除了我们就可以看到隐藏的信息隐藏所有那些红点。 49 00:03:02,630 --> 00:03:07,310 然后调整是一个程序,给定一个文件 50 00:03:07,310 --> 00:03:11,490 然后给予它输出的文件的名称,然后给出一个数字,以及 51 00:03:11,490 --> 00:03:16,850 实际上将调整该位图的大小,整数的值。 52 00:03:16,850 --> 00:03:19,240 最后,我们有“恢复”的pset。 53 00:03:19,240 --> 00:03:24,160 我们有一个记忆卡,然后恢复所有的照片 54 00:03:24,160 --> 00:03:25,920 被意外删除, 55 00:03:25,920 --> 00:03:31,420 但是,正如我们将要学习的,而不是被真正删除,并从文件中删除; 56 00:03:31,420 --> 00:03:38,470 我们刚刚失去了他们在该文件中,但我们要恢复的。 57 00:03:38,470 --> 00:03:44,950 >> 大。因此,进入文件I / O具体而言,这是一个整体,你将要使用的功能列表。 58 00:03:44,950 --> 00:03:49,840 你已经看到了一点点的FOPEN的基本知识,FREAD和FWRITE, 59 00:03:49,840 --> 00:03:54,350 但是,我们要进一步研究的一些文件I / O功能,如的fputc, 60 00:03:54,350 --> 00:03:56,930 在你只写一个字符的时间, 61 00:03:56,930 --> 00:04:02,000 FSEEK,在那里你一种向前和向后移动文件指针位置, 62 00:04:02,000 --> 00:04:05,770 然后一些人。但我们会进入一个位在pset的。 63 00:04:08,050 --> 00:04:13,100 >> 因此,首先进入文件I / O之前,我们去到的pset 64 00:04:13,100 --> 00:04:19,860 打开一个文件,例如,你有什么做的实际上是一个指针,指向该文件。 65 00:04:19,860 --> 00:04:22,710 因此,我们有一个FILE *指针。 66 00:04:22,710 --> 00:04:27,140 在这种情况下,我称这是一个指针,因为这将是我的INFILE。 67 00:04:27,140 --> 00:04:33,340 所以我要使用该功能打开,然后文件的文件名 68 00:04:33,340 --> 00:04:36,360 然后我要的模式,在这模式下,将处理文件。 69 00:04:36,360 --> 00:04:42,080 因此,有“R”在这种情况下,阅读,“W”的写作,然后“A”为追加。 70 00:04:42,080 --> 00:04:44,270 例如,当你正在处理一个INFILE 71 00:04:44,270 --> 00:04:47,310 所有你想要做的是阅读的比特和字节存储在那里, 72 00:04:47,310 --> 00:04:50,420 那么你可能会想使用“r”作为您的模式。 73 00:04:50,420 --> 00:04:54,520 当你想真正写,一种新的文件, 74 00:04:54,520 --> 00:04:57,220 然后我们要做的是,我们要打开新文件 75 00:04:57,220 --> 00:05:02,410 使用“w”模式编写。 76 00:05:02,410 --> 00:05:07,540 >> 那么,当你读入的文件,其结构如下。 77 00:05:07,540 --> 00:05:14,930 首先,你的struct的指针将包含你正在读的字节。 78 00:05:14,930 --> 00:05:19,830 所以这将是你正在读的字节的结束位置。 79 00:05:19,830 --> 00:05:23,360 然后,你要显示的大小,基本上是想有多少个字节 80 00:05:23,360 --> 00:05:30,100 你的程序读入的文件的大小基本上是一个元素, 81 00:05:30,100 --> 00:05:32,620 然后你要指定你想读多少个元素。 82 00:05:32,620 --> 00:05:34,980 最后,你必须知道你正在阅读, 83 00:05:34,980 --> 00:05:37,580 所以这将是您在指针。 84 00:05:37,580 --> 00:05:41,780 我的颜色编码,这是因为FREAD也很类似FWRITE, 85 00:05:41,780 --> 00:05:47,050 但你要确保你使用正确的顺序, 86 00:05:47,050 --> 00:05:51,960 确保你实际写入或读取正确的文件。 87 00:05:54,910 --> 00:05:58,610 >> 那么像以前,如果我们有元素的大小,以及元素的数目, 88 00:05:58,610 --> 00:06:00,600 那么我们就可以在这里玩一点点。 89 00:06:00,600 --> 00:06:06,810 假如我有一只狗的结构,这样的话,我想读的两条狗在一个时间。 90 00:06:06,810 --> 00:06:12,450 有什么我可以做的,是说一个元素的大小将是一只狗的大小 91 00:06:12,450 --> 00:06:14,770 我要到实际读取他们两个人。 92 00:06:14,770 --> 00:06:18,290 另外,我可以做什么,说我只是要读一个元素 93 00:06:18,290 --> 00:06:21,340 一个元素将是两只狗的大小。 94 00:06:21,340 --> 00:06:24,320 所以这是类似的,你可以玩耍的大小和数量 95 00:06:24,320 --> 00:06:28,250 根据更直观的给你。 96 00:06:28,250 --> 00:06:30,810 >> 好的。所以现在我们得到的书面文件。 97 00:06:30,810 --> 00:06:36,880 当你想要写一个文件,第一个参数实际上是你正在阅读。 98 00:06:36,880 --> 00:06:42,050 所以,基本上,你要写入文件的数据, 99 00:06:42,050 --> 00:06:44,490 这是满分指针末端。 100 00:06:44,490 --> 00:06:47,670 所以,当你正在处理的pset中,确保你不要混淆。 101 00:06:47,670 --> 00:06:50,480 也许有并排的定义。 102 00:06:50,480 --> 00:06:58,090 你可以把定义在本手册中键入man,然后FWRITE,例如, 103 00:06:58,090 --> 00:06:59,950 在终端上,或者你可以参考这个幻灯片 104 00:06:59,950 --> 00:07:03,570 并确保您使用的是正确的。 105 00:07:03,570 --> 00:07:08,700 FWRITE,所以,再一次,当你有一个文件,你要写入, 106 00:07:08,700 --> 00:07:14,290 那将是最后一个参数,那将是一个指针,指向该文件。 107 00:07:14,290 --> 00:07:18,670 那么,我们如何处理也许是几个字节写一次, 108 00:07:18,670 --> 00:07:21,820 但说你只想写的只是一个单一的字符。 109 00:07:21,820 --> 00:07:25,940 正如我们将看到在这个例子中,我们将不得不使用的位图,。 110 00:07:25,940 --> 00:07:32,180 这时候,我们可以使用的fputc,基本上只是把一个字符的时间,字符, 111 00:07:32,180 --> 00:07:37,050 文件指针,这就是我们的了指针。 112 00:07:38,700 --> 00:07:41,560 所以,每当我们寻求或写在一个文件中, 113 00:07:41,560 --> 00:07:44,690 该文件是跟踪我们的地方。 114 00:07:44,690 --> 00:07:47,810 因此,它是一种指针,文件指针位置。 115 00:07:47,810 --> 00:07:54,330 所以每当我们到一个文件中写入或读取, 116 00:07:54,330 --> 00:07:56,760 该文件实际上还记得它在哪里, 117 00:07:56,760 --> 00:07:59,270 因此它继续从光标所在。 118 00:07:59,270 --> 00:08:03,970 这可能是有益的,当你想,说,读一定量做一些事情 119 00:08:03,970 --> 00:08:06,160 然后阅读以下金额, 120 00:08:06,160 --> 00:08:10,700 但有时我们可能要回去,其实从一定的参考价值。 121 00:08:10,700 --> 00:08:16,870 那么的fseek函数,它的作用是让我们将光标移到特定的文件 122 00:08:16,870 --> 00:08:19,680 一定数目的字节。 123 00:08:19,680 --> 00:08:24,260 然后我们要做的是指定的参考价值。 124 00:08:24,260 --> 00:08:31,520 因此,无论是向前或向后移动光标目前, 125 00:08:31,520 --> 00:08:35,750 或者我们可以指定它应该只是从开头的文件 126 00:08:35,750 --> 00:08:37,090 或从该文件的结束。 127 00:08:37,090 --> 00:08:41,230 所以你可以通过在正面或负面的价值金额, 128 00:08:41,230 --> 00:08:44,960 将一种向前或向后移动光标。 129 00:08:46,170 --> 00:08:51,920 >> 在我们进入其他pset,任何问题上的文件I / O? 130 00:08:53,860 --> 00:08:59,990 好吧。当我们进入更多的例子,随意停止我的问题。 131 00:08:59,990 --> 00:09:06,930 >> 因此,在谁是凶手,你交给一个位图文件,这个红色的幻灯片上的类似, 132 00:09:06,930 --> 00:09:14,510 和它看起来像这样 - 一堆红点 - 你真的不知道写的什么。 133 00:09:14,510 --> 00:09:23,310 如果你眯着眼睛,你也许可以看到一个淡蓝色的颜色殿内正中。 134 00:09:23,310 --> 00:09:26,270 从本质上讲,这是其中的文本存储。 135 00:09:26,270 --> 00:09:30,270 有一宗谋杀案发生这种情况,我们需要找出是谁做的。 136 00:09:30,270 --> 00:09:36,760 为了做到这一点,我们需要一种转换图像转换为可读格式。 137 00:09:36,760 --> 00:09:42,740 如果你们遇到过,有时会有小的包 138 00:09:42,740 --> 00:09:48,510 在这里您将有一个放大镜,用一个红色的膜。任何人?是啊。 139 00:09:48,510 --> 00:09:52,770 所以,你会交到这样的事情,你将有一个放大镜 140 00:09:52,770 --> 00:09:58,130 红色薄膜,你需要把它的形象, 141 00:09:58,130 --> 00:10:03,410 你就可以看到其中隐藏的信息。 142 00:10:03,410 --> 00:10:07,080 我们没有一个放大镜红膜,所以不是我们要创建我们自己的 143 00:10:07,080 --> 00:10:09,060 在此pset中。 144 00:10:09,060 --> 00:10:15,760 这样一来,用户要输入的侦探小说,然后线索,BMP, 145 00:10:15,760 --> 00:10:18,800 所以这是infile中的红点消息, 146 00:10:18,800 --> 00:10:23,550 然后他们说,将是verdict.bmp我们outfile中。 147 00:10:23,550 --> 00:10:27,900 因此,它要创建一个新的位图图像,类似的线索之一 148 00:10:27,900 --> 00:10:32,600 除了以可读的格式,我们可以看到隐藏的信息。 149 00:10:32,600 --> 00:10:37,550 >> 既然我们要处理的编辑和操纵某种形式的位图, 150 00:10:37,550 --> 00:10:42,400 我们要深入到这些位图文件的结构种。 151 00:10:42,400 --> 00:10:48,130 我们走过去,这一点在课堂上,但让我们看看他们更多一些。 152 00:10:48,130 --> 00:10:51,740 位图是本质上只是一个字节安排 153 00:10:51,740 --> 00:10:55,790 在我们所指定的字节的意思是什么。 154 00:10:55,790 --> 00:11:00,540 因此,这里是有点像一个地图的位图图像 155 00:11:00,540 --> 00:11:08,550 说,它开始与一些头文件,开始在那里的一些信息。 156 00:11:08,550 --> 00:11:16,540 您看到的大小,字节数14位图图像显示, 157 00:11:16,540 --> 00:11:18,520 它继续。 158 00:11:18,520 --> 00:11:23,810 那么是什么在这里,我们真正感兴趣的字节数54左右开始。 159 00:11:23,810 --> 00:11:26,060 我们这些RGB三元组。 160 00:11:26,060 --> 00:11:30,760 会做的,是包含的实际像素的颜色值。 161 00:11:30,760 --> 00:11:35,950 一切都在头以上,一些信息 162 00:11:35,950 --> 00:11:41,240 对应的图像的大小,图像的宽度和高度。 163 00:11:41,240 --> 00:11:44,930 当我们去填充后,我们将看到为什么大小的图像 164 00:11:44,930 --> 00:11:48,670 可能会对不同比的宽度或高度。 165 00:11:48,670 --> 00:11:54,240 那么这些代表 - 这些位图图像的字节序列 - 166 00:11:54,240 --> 00:11:59,370 我们可以做什么,说好了,我会记住,在指数14, 167 00:11:59,370 --> 00:12:03,380 这就是的大小,例如,而是我们要做的是什么使这更容易 168 00:12:03,380 --> 00:12:06,020 被封装在一个结构。 169 00:12:06,020 --> 00:12:08,880 因此,我们有两个结构,对我们来说,BITMAPFILEHEADER 170 00:12:08,880 --> 00:12:10,440 和BITMAPINFOHEADER, 171 00:12:10,440 --> 00:12:14,840 所以每当我们阅读到该文件,默认情况下它会为了, 172 00:12:14,840 --> 00:12:22,360 等,以便它也是要填写到变量,如biWidth和biSize。 173 00:12:25,270 --> 00:12:31,230 然后最后,每一个像素由三个字节表示。 174 00:12:31,230 --> 00:12:35,500 第一个是蓝色的量,在像素中,第二个是绿色的量, 175 00:12:35,500 --> 00:12:41,120 最后,红色,其中0基本上是没有没有绿色或蓝色或无红 176 00:12:41,120 --> 00:12:43,720 然后ff是最大值。 177 00:12:43,720 --> 00:12:46,800 这是十六进制值。 178 00:12:46,800 --> 00:12:53,870 那么,如果我们有FF0000,然后,对应于最大数量的蓝色 179 00:12:53,870 --> 00:12:58,890 ,然后没有绿色,没有红色的,这样的话,会给我们一个蓝色像素。 180 00:12:58,890 --> 00:13:04,190 然后,如果我们有FF的所有一刀切,那么这意味着我们有一个白色像素。 181 00:13:04,190 --> 00:13:11,370 这是一种相反通常,当我们说RGB。它实际上是要BGR。 182 00:13:12,750 --> 00:13:18,990 >> 所以,如果我们真正寻找到一个位图图像的一个例子 - 让我拉一起来这里。 183 00:13:31,560 --> 00:13:33,830 这是小了点。 184 00:13:39,890 --> 00:13:47,840 我放大,我们可以看到它的像素化。它看起来像块的颜色。 185 00:13:47,840 --> 00:13:50,110 你有白块,然后红色块。 186 00:13:50,110 --> 00:13:53,700 如果您在Microsoft Paint发挥,例如,你可以做这样的事情 187 00:13:53,700 --> 00:13:58,960 由基本上只是画的某些方块以特定的顺序。 188 00:13:58,960 --> 00:14:08,060 那么这将转换为位图中如下。 189 00:14:08,060 --> 00:14:15,710 在这里,我们第一个白色像素,所有f的,然后我们有红色像素, 190 00:14:15,710 --> 00:14:19,910 由0000FF表示。 191 00:14:19,910 --> 00:14:27,940 所以,我们的字节序列表示的位图图像去看看。 192 00:14:27,940 --> 00:14:32,230 那么,我在这里所做的只是写出来的所有字节,然后在红色着色 193 00:14:32,230 --> 00:14:37,550 所以,你可以看到那种,如果你眯着眼睛一点点,这样的表示了一个笑脸。 194 00:14:40,180 --> 00:14:46,390 >> 位图图像是我工作的方式,设想它基本上是作为一个网格。 195 00:14:46,390 --> 00:14:54,940 并且默认情况下,每行的网格是一个4字节的倍数。 196 00:15:00,520 --> 00:15:07,060 如果我们看一下在一个位图图像,你填写的每一个值。 197 00:15:07,060 --> 00:15:17,370 例如,您可能有一个红色的,绿色的,蓝色的, 198 00:15:17,370 --> 00:15:24,950 但你必须确保图像被填充在与四个字节的倍数。 199 00:15:24,950 --> 00:15:32,200 所以,如果我希望我的3块宽的图像,那么我将不得不放了一个空值 200 00:15:32,200 --> 00:15:35,640 中的最后一个,使其四的倍数。 201 00:15:35,640 --> 00:15:39,530 那么我想补充的东西,我们称之为填充。 202 00:15:39,530 --> 00:15:43,750 我只是要表明,有一个x。 203 00:15:44,920 --> 00:15:54,160 现在说,我们想要的是7个像素的图像,例如。 204 00:15:54,160 --> 00:15:59,550 我们有1,2,3,4,5,6,7, 205 00:16:04,750 --> 00:16:07,000 所有这一切都填充有颜色。 206 00:16:07,000 --> 00:16:10,620 位图图像的工作方式是,我们需要一个8。 207 00:16:10,620 --> 00:16:12,460 现在,我们有1,2,3,4,5,6,7。 208 00:16:12,460 --> 00:16:19,360 我们需要8个空格的正确读出的位图图像。 209 00:16:19,360 --> 00:16:25,600 那么我们需要做的只是一点点填充添加 210 00:16:25,600 --> 00:16:29,430 以确保所有的宽度是均匀的 211 00:16:29,430 --> 00:16:34,260 和所有的宽度是4的倍数。 212 00:16:42,110 --> 00:16:47,310 所以,我曾表示,填充x或波浪线, 213 00:16:47,310 --> 00:16:53,880 但在实际的位图图像的填充表示由十六进制的0。 214 00:16:53,880 --> 00:16:57,340 因此,这将是一个单一的字符,0。 215 00:16:58,980 --> 00:17:06,329 可能会派上用场的,是xxd命令。 216 00:17:06,329 --> 00:17:11,220 它的作用是告诉你,像类似我以前的笑脸 217 00:17:11,220 --> 00:17:15,630 当我真正打印出每种颜色的像素 218 00:17:15,630 --> 00:17:21,800 颜色编码,当您运行XXD用下面的命令, 219 00:17:21,800 --> 00:17:28,670 然后,它实际上会打印出这些像素的颜色是什么。 220 00:17:28,670 --> 00:17:33,810 你必须做的是,在这里我表示,如第54 221 00:17:33,810 --> 00:17:36,530 说,我要在第54个字节开始 222 00:17:36,530 --> 00:17:40,820 因为在此之前,记住,如果我们回头看地图的位图, 223 00:17:40,820 --> 00:17:42,690 这是所有的头信息之类的东西。 224 00:17:42,690 --> 00:17:46,280 但是,我们真正关心的是实际像素,显示的颜色。 225 00:17:46,280 --> 00:17:52,700 因此,通过增加标志,第54条,我们能够看到的颜色值。 226 00:17:52,700 --> 00:17:56,020 不用担心复杂的标志之类的东西。 227 00:17:56,020 --> 00:18:05,020 在问题设置规范,你会如何使用XXD显示像素的方向。 228 00:18:07,070 --> 00:18:15,590 所以,如果你在这里看到的,它看起来像一个绿色的盒子,这个小东西。 229 00:18:15,590 --> 00:18:23,610 我颜色编码的00FF00,基本上可以说没有蓝色的,有很多绿色,没有红色的。 230 00:18:23,610 --> 00:18:26,370 因此,对应于绿色。 231 00:18:26,370 --> 00:18:31,920 当你看到这里,我们看到了一个绿色的长方形。 232 00:18:31,920 --> 00:18:36,660 这绿色的长方形只有3个像素宽,所以我们必须做什么 233 00:18:36,660 --> 00:18:44,350 以确保4宽的图像是一个多添加额外的填充。 234 00:18:44,350 --> 00:18:49,460 这样的话,你怎么看这些0。 235 00:18:49,460 --> 00:18:54,510 这实际上是调整大小的pset的结果, 236 00:18:54,510 --> 00:19:01,350 基本上采取的位图,然后把它做大了4。 237 00:19:01,350 --> 00:19:09,380 因此,我们看到的是,其实这个图像的宽度为12像素,但12是4的倍数, 238 00:19:09,380 --> 00:19:12,940 ,所以我们没有看到任何结束时为0,因为我们不需要添加任何 239 00:19:12,940 --> 00:19:19,070 因为它的完全填充。它没有任何更多的空间。 240 00:19:20,720 --> 00:19:23,470 >> 好吧。任何填充的问题吗? 241 00:19:25,150 --> 00:19:27,460 好吧。酷。 242 00:19:27,460 --> 00:19:32,520 >> 正如我之前提到的,只是一个位图的字节序列。 243 00:19:32,520 --> 00:19:39,170 因此,我们所拥有的,而不是确切的字节数进行跟踪 244 00:19:39,170 --> 00:19:47,050 对应于一个特定的元素,我们实际上已经创建了一个结构来表示,。 245 00:19:47,050 --> 00:19:50,930 所以,我们是结构的一个RGBTRIPLE。 246 00:19:50,930 --> 00:19:54,590 只要你有一个RGB三元组的一个实例, 247 00:19:54,590 --> 00:20:00,970 因为这是一个类型定义结构,然后您可以访问rgbtBlue的变量, 248 00:20:00,970 --> 00:20:09,520 类似地,绿色和红色的变量,这将表明多少蓝色,绿色,红色, 249 00:20:09,520 --> 00:20:11,580 分别,你有。 250 00:20:11,580 --> 00:20:16,800 >> 因此,如果我们有蓝色的变量设置为0,绿色设置为FF, 251 00:20:16,800 --> 00:20:22,060 这是最大的值,可以有,然后红色的变量设置为0, 252 00:20:22,060 --> 00:20:27,870 然后这个特殊的RGB三什么颜色代表什么呢? >> [学生]绿色。 253 00:20:27,870 --> 00:20:29,150 绿色。没错。 254 00:20:29,150 --> 00:20:34,480 这将是有益的知道,只要你有一个RGB三元组的一个实例, 255 00:20:34,480 --> 00:20:41,340 实际上,可以访问的颜色量 - 蓝色,绿色和红色 - 分开。 256 00:20:43,350 --> 00:20:54,900 >> 现在,我们已经讨论过的结构,让我们来看看在BMP文件。 257 00:20:54,900 --> 00:20:57,870 这些为你做的是结构。 258 00:20:57,870 --> 00:21:01,820 在这里,我们有一个BITMAPFILEHEADER结构。 259 00:21:01,820 --> 00:21:07,610 有趣的是大小。 260 00:21:07,610 --> 00:21:12,660 后来,我们的头部信息,其中有几个很有趣的事情,我们, 261 00:21:12,660 --> 00:21:15,480 即的大小,宽度,和高度。 262 00:21:15,480 --> 00:21:19,170 正如我们将要进入​​以后,当你在阅读该文件, 263 00:21:19,170 --> 00:21:25,500 它会自动读取的,因为我们已经设置的顺序是一样的。 264 00:21:25,500 --> 00:21:31,990 所以biSize将包含对应于该图像的实际大小的正确的字节。 265 00:21:34,700 --> 00:21:40,500 那么在这里,最后,正如我们已经谈到,我们有RGBTRIPLE typedef结构。 266 00:21:40,500 --> 00:21:46,840 我们有rgbtBlue,绿色,红色与。 267 00:21:48,210 --> 00:21:49,340 >> 大。好吧。 268 00:21:49,340 --> 00:21:56,360 现在,我们一点点了解位图,了解我们有一个文件头 269 00:21:56,360 --> 00:22:00,790 和信息头与它,然后在那之后,我们有一个有趣的东西 270 00:22:00,790 --> 00:22:05,110 的颜色,这些颜色RGBTRIPLE结构表示的, 271 00:22:05,110 --> 00:22:12,710 和那些,反过来,具有相关联的三个值的蓝色,绿色和红色。 272 00:22:12,710 --> 00:22:17,270 >> 所以,现在,我们可以一种想恢复一点。 273 00:22:17,270 --> 00:22:20,130 抱歉。想想谁是凶手。 274 00:22:20,130 --> 00:22:25,750 当我们有我们的线索文件,然后我们想要做的是阅读像素的像素 275 00:22:25,750 --> 00:22:33,860 然后以某种方式改变那些像素,这样我们就可以输出到一个可读的格式。 276 00:22:33,860 --> 00:22:41,020 因此,对于输出,我们要去,写像素的像素到verdict.bmp文件。 277 00:22:41,020 --> 00:22:45,120 这是种有很多事情要做。我们意识到这一点。 278 00:22:45,120 --> 00:22:49,860 所以,我们做了什么,我们实际上已经为您提供了copy.c. 279 00:22:49,860 --> 00:22:57,610 路径'%s'不只是一个给定的位图文件的精确副本,然后将它输出。 280 00:22:57,610 --> 00:23:01,900 因此,这已为您打开该文件,读取像素由像素 281 00:23:01,900 --> 00:23:04,510 然后将数据写入到输出文件中。 282 00:23:04,510 --> 00:23:07,080 >> 让我们来看看在那。 283 00:23:13,390 --> 00:23:18,290 这是确保正确使用, 284 00:23:18,290 --> 00:23:22,640 这里的文件名。 285 00:23:22,640 --> 00:23:29,940 这是什么做的是设置输入文件是什么,我们已经通过在这里的infile, 286 00:23:29,940 --> 00:23:34,750 这是我们的第二个命令行参数。 287 00:23:34,750 --> 00:23:37,640 检查,以确保我们可以打开该文件。 288 00:23:38,960 --> 00:23:44,860 检查,以确保我们可以建立一个新的输出文件在这里。 289 00:23:45,630 --> 00:23:53,270 这是什么在这里所做的,只是基本上从一开始就读取位图文件。 290 00:23:53,270 --> 00:23:56,700 开始的时候,我们知道,包含BITMAPFILEHEADER, 291 00:23:56,700 --> 00:24:03,200 这些序列位直接填写在BITMAPFILEHEADER。 292 00:24:03,200 --> 00:24:07,940 所以我们在这里说,BITMAPFILEHEADER BF - 293 00:24:07,940 --> 00:24:13,150 这是我们的新的变量类型BITMAPFILEHEADER - 294 00:24:13,150 --> 00:24:22,560 我们打​​算把我们从指针内BF,这是我们的INFILE。 295 00:24:22,560 --> 00:24:23,970 我们读多少? 296 00:24:23,970 --> 00:24:32,160 我们读我们需要多少字节包含整个BITMAPFILEHEADER。 297 00:24:32,160 --> 00:24:34,660 同样的,这就是我们做的头部信息。 298 00:24:34,660 --> 00:24:39,010 因此,我们将继续沿着我们的文件将infile, 299 00:24:39,010 --> 00:24:44,360 正在阅读这些比特和字节,和我们直接插入在 300 00:24:44,360 --> 00:24:47,880 在这些情况下,我们正在做的变量。 301 00:24:49,370 --> 00:24:53,800 在这里,我们只是确保该位图是一个位图。 302 00:24:57,670 --> 00:25:01,030 >> 现在我们有一个输出文件,对不对? 303 00:25:01,030 --> 00:25:04,420 因此,它代表我们创建它时,它基本上是空的。 304 00:25:04,420 --> 00:25:07,710 因此,我们必须从根本上从头开始创建一个新的位图。 305 00:25:07,710 --> 00:25:12,280 我们做的是,我们必须确保,我们将在文件头 306 00:25:12,280 --> 00:25:16,850 和头文件的信息一样将infile。 307 00:25:16,850 --> 00:25:22,850 我们做的是我们写的 - 并且要记住,BF是变量 308 00:25:22,850 --> 00:25:29,300 类型BITMAPFILEHEADER,所以我们要做的是,我们只是使用这些内容 309 00:25:29,300 --> 00:25:34,980 写入outfile中。 310 00:25:36,550 --> 00:25:38,510 在这里,记得我们谈到了填充, 311 00:25:38,510 --> 00:25:47,820 如何重要的是要确保,我们的像素量是4的倍数。 312 00:25:47,820 --> 00:25:52,790 这是一个非常有用的公式来计算你有多少填充 313 00:25:52,790 --> 00:25:57,670 您的文件的宽度。 314 00:25:57,670 --> 00:26:04,120 我希望你们要记住,在路径'%s',我们有一个公式计算填充。 315 00:26:04,120 --> 00:26:07,970 可以吗?所以每个人都记住这一点。大。 316 00:26:07,970 --> 00:26:14,050 那么什么路径'%s'下的是它遍历所有的扫描线。 317 00:26:14,050 --> 00:26:23,730 它首先通过行,然后将它读取每三 318 00:26:23,730 --> 00:26:26,920 然后将数据写入到输出文件。 319 00:26:26,920 --> 00:26:33,120 那么在这里,我们正在阅读的时间只有一个RGB三 320 00:26:33,120 --> 00:26:39,860 然后把同样的三到outfile中。 321 00:26:41,120 --> 00:26:48,340 棘手的部分是填充不是RGB三, 322 00:26:48,340 --> 00:26:55,200 ,所以我们不能只是读,填充量的RGB三元组。 323 00:26:55,200 --> 00:27:01,460 我们要做的其实只是我们的文件位置指示器移动,移动的光标, 324 00:27:01,460 --> 00:27:06,840 种跳过所有的填充,使我们在下一行。 325 00:27:06,840 --> 00:27:12,990 这是什么做的是复制显示你如何,你可能要添加的填充。 326 00:27:12,990 --> 00:27:14,990 因此,我们计算我们需要多少填充, 327 00:27:14,990 --> 00:27:18,220 所以,这意味着我们需要填充的0。 328 00:27:18,220 --> 00:27:24,510 这是一个循环,将填补数的0到我们的OUTFILE。 329 00:27:24,510 --> 00:27:31,170 然后,终于,您可以关闭这两个文件。关闭的infile和outfile中。 330 00:27:31,170 --> 00:27:34,870 >> 所以这就是的copy.c作品, 331 00:27:34,870 --> 00:27:37,430 而这将是非常有用的。 332 00:27:39,720 --> 00:27:43,750 而不是仅仅居然直接复制和粘贴 333 00:27:43,750 --> 00:27:46,800 或者只是看着它,输入任何你想要的, 334 00:27:46,800 --> 00:27:49,440 你可能只是想在终端中执行此命令, 335 00:27:49,440 --> 00:27:54,520 CP路径'%s'whodunit.c,这将创建一个新的文件,whodunit.c, 336 00:27:54,520 --> 00:27:58,330 包含的确切内容相同的复制品。 337 00:27:58,330 --> 00:28:03,880 那么,我们能做些什么,作为一个框架,用于构建和编辑 338 00:28:03,880 --> 00:28:06,900 我们的侦探小说文件。 339 00:28:08,500 --> 00:28:14,670 >> 这些都是我们的待办事项给谁是凶手,但什么copy.c 340 00:28:14,670 --> 00:28:16,730 实际上他们大多数人对我们的照顾。 341 00:28:16,730 --> 00:28:21,900 所以,接下来我们需要做的是根据需要改变像素 342 00:28:21,900 --> 00:28:25,920 真正使文件可读。 343 00:28:25,920 --> 00:28:32,960 请记住,对于一个给定的像素三倍,所以对于一个给定的变量的类型RGBTRIPLE的, 344 00:28:32,960 --> 00:28:35,990 可以访问的蓝色,绿色和红色的值。 345 00:28:35,990 --> 00:28:38,670 这是怎么回事就派上用场了,因为如果你可以访问他们, 346 00:28:38,670 --> 00:28:41,770 这意味着,您还可以检查它们, 347 00:28:41,770 --> 00:28:45,430 这意味着,你也可以改变他们。 348 00:28:45,430 --> 00:28:49,430 >> 所以,当我们又回到了我们的红色放大镜的例子, 349 00:28:49,430 --> 00:28:53,390 基本上,这是对我们的一种过滤器。 350 00:28:53,390 --> 00:28:58,160 所以我们想要做的是,我们要过滤所有的三元组来 351 00:28:58,160 --> 00:29:01,240 有几种不同的方法来做到这一点。 352 00:29:01,240 --> 00:29:07,100 基本上,你可以有你想要的任何类型的过滤器。 353 00:29:07,100 --> 00:29:09,890 也许你想改变所有红色像素 354 00:29:09,890 --> 00:29:13,570 也许你想改变不同的颜色,不同的颜色的像素。 355 00:29:13,570 --> 00:29:15,400 这是给你的。 356 00:29:15,400 --> 00:29:19,580 记住,你可以检查像素是什么颜色的 357 00:29:19,580 --> 00:29:23,000 然后你也可以改变它的时候,你会通过。 358 00:29:24,410 --> 00:29:26,420 >> 好吧。所以,谁是凶手。 359 00:29:26,420 --> 00:29:32,760 一旦运行了谁是凶手,你会知道谁是犯罪的罪魁祸首。 360 00:29:32,760 --> 00:29:35,540 >> 现在,我们将去调整大小。 361 00:29:35,540 --> 00:29:37,990 我们将仍然可以处理位图。 362 00:29:37,990 --> 00:29:40,750 我们要做的是,我们将有一个输入位图 363 00:29:40,750 --> 00:29:45,890 然后我们要通过一个号码,然后得到一个outfile中的位图 364 00:29:45,890 --> 00:29:51,380 基本上是我们INFILE比例由n。 365 00:29:54,670 --> 00:30:01,450 说我的文件只是一个像素大。 366 00:30:01,450 --> 00:30:09,100 然后,如果我的n为3,缩放,3,然后我会重复n次的像素, 367 00:30:09,100 --> 00:30:14,410 如此3遍,然后还扩大了3倍为好。 368 00:30:14,410 --> 00:30:17,840 所以,你看我将其扩大为水平和垂直方向。 369 00:30:17,840 --> 00:30:19,680 >> 那么这里是一个例子。 370 00:30:19,680 --> 00:30:27,590 如果您有n = 2时,您会看到第一个蓝色像素重复两次 371 00:30:27,590 --> 00:30:30,930 水平良好两次垂直。 372 00:30:30,930 --> 00:30:38,040 然后继续,让你有一个直接的原始图像缩放2。 373 00:30:40,920 --> 00:30:47,600 >> 那么,如果我们要详细的伪代码,我们要打开的文件。 374 00:30:47,600 --> 00:30:49,880 然后知道,如果我们回到这里, 375 00:30:49,880 --> 00:30:54,540 我们看到的宽度与outfile将是不同的宽度将infile。 376 00:30:54,540 --> 00:30:56,130 这是什么意思呢? 377 00:30:56,130 --> 00:31:01,230 这意味着,我们的头信息是不会改变。 378 00:31:01,230 --> 00:31:03,790 因此,我们会想要做的是更新的头信息, 379 00:31:03,790 --> 00:31:11,820 知道,当我们读到的文件,如果你经营的copy.c框架, 380 00:31:11,820 --> 00:31:17,570 我们已经有了一个变量,它的大小是什么之类的东西。 381 00:31:17,570 --> 00:31:24,060 所以,一旦你有,你可能想要做的是改变这些特定的变量。 382 00:31:24,060 --> 00:31:29,380 请记住,如果你有一个struct,你如何访问内的变量。 383 00:31:29,380 --> 00:31:32,080 您可以使用点操作符,对不对? 384 00:31:32,080 --> 00:31:36,420 那么,你知道,你需要改变的头信息。 385 00:31:36,480 --> 00:31:41,030 所以这里只是一个将要改变你的文件列表中的实际元素。 386 00:31:41,030 --> 00:31:45,180 文件的大小将被改变的图像,以及在宽度和高度。 387 00:31:45,180 --> 00:31:50,080 因此,然后回过头来在地图上的位图, 388 00:31:50,080 --> 00:31:57,730 看是否包含该信息的文件头或头文件的信息 389 00:31:57,730 --> 00:32:00,920 然后根据需要进行更改。 390 00:32:05,010 --> 00:32:12,470 同样,说CP路径'%s'resize.c。 391 00:32:12,470 --> 00:32:19,270 这意味着,resize.c现在包含一切的包含在复制 392 00:32:19,270 --> 00:32:24,490 ,因为副本为我们提供了在每个扫描行的像素由像素的阅读方式。 393 00:32:24,490 --> 00:32:29,860 但现在,而不是仅仅改变的值,就像我们在谁是凶手, 394 00:32:29,860 --> 00:32:37,980 我们想要做的是我们要写入多个像素 395 00:32:37,980 --> 00:32:43,580 只要作为我们n是大于1的。 396 00:32:43,580 --> 00:32:47,110 >> 然后我们想要做的是,我们要伸展它由n个水平, 397 00:32:47,110 --> 00:32:50,490 以及由n个垂直伸展。 398 00:32:50,490 --> 00:32:52,710 我们怎么可能这样做呢? 399 00:32:52,710 --> 00:32:56,890 假设n是2,你有这样的INFILE。 400 00:32:56,890 --> 00:32:58,730 你的光标将开始在第一个, 401 00:32:58,730 --> 00:33:03,530 你想要做什么,如果n是2,你要打印2。 402 00:33:03,530 --> 00:33:05,490 所以,你打印2。 403 00:33:05,490 --> 00:33:10,830 然后将光标移动到下一个像素,它是红色的, 404 00:33:10,830 --> 00:33:18,400 这将打印出的那些红色的,其追加到它做什么之前。 405 00:33:18,400 --> 00:33:26,280 然后将光标移动到下一个像素,并吸引2。 406 00:33:26,280 --> 00:33:37,180 如果你回头看看在这里copy.c框架,这是什么做的 407 00:33:37,180 --> 00:33:42,830 它创建了一个新的RGB三,一个新的变量三。 408 00:33:42,830 --> 00:33:50,500 这里读入它,它会读取从INFILE 1 RGBTRIPLE 409 00:33:50,500 --> 00:33:53,470 ,并将其存储,三联变量的内部。 410 00:33:53,470 --> 00:33:57,590 那么你确实有一个变量,代表特定的像素。 411 00:33:57,590 --> 00:34:05,290 然后,当你写,你可能想要做的是包住的fwrite语句转换成一个for循环 412 00:34:05,290 --> 00:34:11,080 ,将其写入到您的outfile中根据需要尽可能多的时间。 413 00:34:17,449 --> 00:34:20,100 这是很简单的。 414 00:34:20,200 --> 00:34:27,590 只需基本上重复n次写作过程中它的规模水平。 415 00:34:27,590 --> 00:34:32,969 >> 那么,我们一定要记住,我们的填充是不会改变的。 416 00:34:47,350 --> 00:34:53,020 在此之前,说我们有一些东西长度为3。 417 00:34:53,020 --> 00:35:00,130 然后,我们想添加多少填充?只是多了一个4的倍数。 418 00:35:00,130 --> 00:35:10,480 但说我们在这个特殊的图像缩放为n = 2。 419 00:35:10,480 --> 00:35:16,300 那么我们有多少蓝像素的结束吗?我们有6个。 420 00:35:16,300 --> 00:35:21,470 1,2,3,4,5,6。好的。 421 00:35:21,470 --> 00:35:26,580 图6是不是4的倍数。最近的4的倍数是什么?这将是8。 422 00:35:26,580 --> 00:35:33,200 因此,我们实际上有2个字符填充。 423 00:35:33,200 --> 00:35:38,720 >> 如果有谁还记得我们有一个公式来计算填充 424 00:35:38,720 --> 00:35:41,350 和可能是什么? 425 00:35:41,350 --> 00:35:45,160 [听不见的学生响应呀,copy.c.右。 426 00:35:45,160 --> 00:35:49,800 有一个公式计算你有多少填充在路径'%s' 427 00:35:49,800 --> 00:35:53,810 给定一个特定的位图图像的宽度。 428 00:35:53,810 --> 00:36:02,950 那么,那将是非常有用的,当您需要添加一定量的填充 429 00:36:02,950 --> 00:36:06,160 找出你需要添加多少填充。 430 00:36:10,820 --> 00:36:15,850 不过,虽然是一个音符,您要确保您使用的是正确的大小。 431 00:36:15,850 --> 00:36:21,410 只是要小心,因为你基本上要处理的两个位图图像。 432 00:36:21,410 --> 00:36:23,410 您要确保您使用的是正确的。 433 00:36:23,410 --> 00:36:26,820 当你计算的填充outfile中,您要使用的宽度与outfile 434 00:36:26,820 --> 00:36:29,860 的宽度,而不是以前的一个。 435 00:36:29,860 --> 00:36:37,240 >> 大。那种需要护理的水平拉伸整个位图图像。 436 00:36:37,240 --> 00:36:41,290 但是,我们想要做的就是伸展和垂直方向。 437 00:36:41,290 --> 00:36:48,760 这将是一个有点棘手,因为当我们已经完成了复制行 438 00:36:48,760 --> 00:36:51,580 和书面行,光标要在年底。 439 00:36:51,580 --> 00:36:56,210 因此,如果我们看了一遍,然后它只是要读入到下一行。 440 00:36:56,210 --> 00:37:03,660 所以我们想要做的是找到某种方式再次复制这些行 441 00:37:03,660 --> 00:37:12,500 或只是一种采取这一行,然后重写一遍。 442 00:37:14,380 --> 00:37:17,940 正如我种提到,有几种不同的方法来做到这一点。 443 00:37:17,940 --> 00:37:23,040 你可以做的是,你要通过读通过特定的扫描线 444 00:37:23,040 --> 00:37:28,560 和在必要时改变它,然后种存储在数组中的所有的那些像素。 445 00:37:28,560 --> 00:37:36,350 后来你知道,你需要再次打印出该数组, 446 00:37:36,350 --> 00:37:39,830 ,所以你可以使用该数组来做到这一点。 447 00:37:39,830 --> 00:37:44,500 做到这一点的另一种方式是你可以复制到下一行, 448 00:37:44,500 --> 00:37:47,950 知道你需要再次复制,所以实际上你的光标移动, 449 00:37:47,950 --> 00:37:50,950 这就是将要使用的方法FSEEK。 450 00:37:50,950 --> 00:37:56,410 你可以将你的光标所有的方式回到,然后再重复复制过程。 451 00:37:56,410 --> 00:38:03,960 >> 因此,如果我们缩放数为n,则多少次,我们要回去 452 00:38:03,960 --> 00:38:10,500 并重写一条线吗? >> [学生] N - 1。 “是的,完美的。 N - 1。 453 00:38:10,500 --> 00:38:14,390 我们已经做了一次了,这样的话,我们将要重复的回头路过程 454 00:38:14,390 --> 00:38:17,460 N - 1倍量。 455 00:38:22,730 --> 00:38:25,860 好吧。所以,你有你的大小调整功能。 456 00:38:25,860 --> 00:38:34,360 >> 现在,我们可以得到一个真正有趣的部分,我最喜欢的pset,这是恢复。 457 00:38:34,360 --> 00:38:39,580 而不是位图,这个时候,我们正在处理的JPEG文件。 458 00:38:39,580 --> 00:38:43,370 我们实际上没有给定文件的JPEG文件一样, 459 00:38:43,370 --> 00:38:46,600 我们基本上是一个原始的记忆卡格式。 460 00:38:46,600 --> 00:38:51,790 因此,这包含一个位的信息和垃圾值开始, 461 00:38:51,790 --> 00:38:57,240 然后它开始和它有一堆的JPEG文件。 462 00:38:57,240 --> 00:39:03,430 但是,我们递上一张卡,我们已经删除了照片; 463 00:39:03,430 --> 00:39:08,300 从本质上讲,我们已经忘记了位于卡内的照片。 464 00:39:08,300 --> 00:39:12,770 那么在恢复我们的任务是去通过此卡格式 465 00:39:12,770 --> 00:39:16,500 再次找到这些图片。 466 00:39:16,500 --> 00:39:23,990 >> 幸运的是,JPEG文件的结构,卡文件是有点帮助。 467 00:39:23,990 --> 00:39:28,850 它肯定是有点麻烦,如果不是在这种特定的格式。 468 00:39:28,850 --> 00:39:40,160 其实每一个JPEG文件有两个可能的序列,上面列出的开始。 469 00:39:40,160 --> 00:39:42,970 基本上,只要你有一个新的JPEG文件, 470 00:39:42,970 --> 00:39:52,720 开始序列FFD8 FFE0或另一个,FFD8 FFE1。 471 00:39:52,720 --> 00:39:59,530 另一个有用的东西知道的是,JPEG文件连续存储。 472 00:39:59,530 --> 00:40:03,380 所以,每当一个JPEG文件的结束,另一个开始。 473 00:40:03,380 --> 00:40:07,070 这样就不会有在值之间有任何种。 474 00:40:07,070 --> 00:40:15,510 一旦你点击开始,如果你已经读一个JPEG的JPEG, 475 00:40:15,510 --> 00:40:21,800 你知道你已经打了结束的上一个和下一个开始。 476 00:40:21,800 --> 00:40:25,890 >> 种形象化,我做了一个示意图。 477 00:40:25,890 --> 00:40:36,910 另一件事对JPEG文件,我们可以阅读他们在一个时间序列中的512个字节, 478 00:40:36,910 --> 00:40:39,380 同样与该卡的开头。 479 00:40:39,380 --> 00:40:43,370 我们并不需要检查每一个字节,因为这会吸。 480 00:40:43,370 --> 00:40:48,200 因此,不是,我们能做些什么,其实只是在512个字节读取一次 481 00:40:48,200 --> 00:40:54,700 然后,而不是检查之间的这些微小的小片, 482 00:40:54,700 --> 00:40:58,640 我们可以只检查开始的512个字节。 483 00:40:58,640 --> 00:41:02,570 从本质上讲,在这幅画中,你看到的是在开头的卡, 484 00:41:02,570 --> 00:41:08,700 你有值的实际JPEG文件本身是不是真的有关。 485 00:41:08,700 --> 00:41:15,830 那么是什么我已经是一个明星来表示两个序列的JPEG。 486 00:41:15,830 --> 00:41:19,910 所以,当你看到一个明星,你知道你有一个JPEG文件。 487 00:41:19,910 --> 00:41:25,030 然后每一个JPEG文件将是一些512字节的倍数 488 00:41:25,030 --> 00:41:27,880 但不一定是相同的多。 489 00:41:27,880 --> 00:41:32,050 你知道你已经达到了另外一个JPEG的方式,是如果你击中​​另一颗恒星, 490 00:41:32,050 --> 00:41:39,090 另一种起始的字节序列。 491 00:41:39,090 --> 00:41:43,330 你在这里的是你有红色的JPEG文件继续,直到你击中的明星, 492 00:41:43,330 --> 00:41:45,150 这是一个新的颜色表示。 493 00:41:45,150 --> 00:41:48,510 您可以继续,那么你击中另一颗恒星,你打另一个JPEG, 494 00:41:48,510 --> 00:41:50,590 你继续一路,直到结束。 495 00:41:50,590 --> 00:41:53,180 你在这里的最后一张照片,粉红的。 496 00:41:53,180 --> 00:41:58,220 去年底,直到你击中的文件结束符。 497 00:41:58,220 --> 00:42:00,820 这将是非常有用的。 498 00:42:00,820 --> 00:42:03,170 >> 有一些主要的takeaways: 499 00:42:03,170 --> 00:42:06,670 卡中的文件无法启动与JPEG, 500 00:42:06,670 --> 00:42:13,350 但,一个JPEG一旦开始所有的JPEG文件存储并排彼此。 501 00:42:17,520 --> 00:42:20,420 >> 一些伪代码的恢复。 502 00:42:20,420 --> 00:42:22,570 首先,我们要打开我们的卡中的文件, 503 00:42:22,570 --> 00:42:27,500 这就是将要使用我们的文件I / O功能。 504 00:42:27,500 --> 00:42:32,430 我们要重复以下过程,直到我们已经走到了尽头的文件。 505 00:42:32,430 --> 00:42:36,450 我们要读512字节的时间。 506 00:42:36,450 --> 00:42:39,180 我在这里说的是,我们将其存储在缓冲区中, 507 00:42:39,180 --> 00:42:46,230 所以基本上举行,512个字节,直到我们知道该怎么做与他们。 508 00:42:46,230 --> 00:42:50,300 然后我们想要做的是,我们要检查我们是否已经打了星型或不。 509 00:42:50,300 --> 00:42:57,960 如果我们碰到一个明星,如果我们碰到一个起始序列, 510 00:42:57,960 --> 00:42:59,980 然后,我们知道,我们已经打了一个新的JPEG文件。 511 00:42:59,980 --> 00:43:08,860 我们将要做的是,我们将要创建一个新的文件在我们pset4目录 512 00:43:08,860 --> 00:43:14,480 继续该文件。 513 00:43:14,480 --> 00:43:18,220 但同时,如果我们已经做了一个JPEG之前, 514 00:43:18,220 --> 00:43:25,620 然后,我们要结束该文件,并将其推的pset4的文件夹, 515 00:43:25,620 --> 00:43:29,780 我们将在这里,因为如果我们不指定,我们已经结束,JPEG文件,该文件存储 516 00:43:29,780 --> 00:43:37,290 基本上,我们将有一个不确定的量。 JPEG文件将永远不会结束。 517 00:43:37,290 --> 00:43:40,840 因此,我们要确保,当我们在阅读中的JPEG文件,并书面, 518 00:43:40,840 --> 00:43:46,590 我们要明确关闭,在打开​​下一个。 519 00:43:46,590 --> 00:43:48,430 我们需要检查几件事情。 520 00:43:48,430 --> 00:43:52,880 我们要检查是否我们在开始一个新的JPEG与我们的缓冲区 521 00:43:52,880 --> 00:43:56,780 并且,如果我们已经找到了一个JPEG前 522 00:43:56,780 --> 00:44:03,930 因为这会稍微改变你的过程。 523 00:44:03,930 --> 00:44:07,880 那么,你通过所有的方式,你打到最后的文件, 524 00:44:07,880 --> 00:44:11,570 然后你会想要做的是,你要关闭当前打开的所有文件。 525 00:44:11,570 --> 00:44:14,100 这将可能是最后的JPEG文件,你有, 526 00:44:14,100 --> 00:44:18,930 以及卡中的文件,你已经处理。 527 00:44:21,940 --> 00:44:28,670 >> 最后的障碍,我们需要解决的是如何使一个JPEG文件 528 00:44:28,670 --> 00:44:31,950 以及如何将其推到该文件夹​​。 529 00:44:33,650 --> 00:44:39,850 pset的要求,每一个JPEG,你觉得在下面的格式, 530 00:44:39,850 --> 00:44:43,990 在那里你有多少jpg文件。 531 00:44:43,990 --> 00:44:50,750 的数量,即使是0,我们把它称为000.jpg。 532 00:44:50,750 --> 00:44:55,730 无论何时你发现在你的程序中的一个JPEG, 533 00:44:55,730 --> 00:44:58,040 你会想要将它命名的顺序,它的发现。 534 00:44:58,040 --> 00:44:59,700 这是什么意思呢? 535 00:44:59,700 --> 00:45:03,530 我们需要跟踪我们发现有多少种 536 00:45:03,530 --> 00:45:08,680 每个JPEG数应该是什么。 537 00:45:08,680 --> 00:45:13,800 在这里,我们将充分利用sprintf函数。 538 00:45:13,800 --> 00:45:17,480 类似printf,它只是打印到终端, 539 00:45:17,480 --> 00:45:23,910 sprintf的打印文件到该文件夹​​中。 540 00:45:23,910 --> 00:45:30,870 因此,这是什么会做,如果我的sprintf,标题,然后还有的字符串, 541 00:45:30,870 --> 00:45:36,660 它会打印出2.JPG。 542 00:45:36,660 --> 00:45:41,020 假设我已经关闭了正确的文件, 543 00:45:41,020 --> 00:45:47,210 将包含的文件,我已经写出来。 544 00:45:47,210 --> 00:45:50,320 但有一件事是代码,我这里有 545 00:45:50,320 --> 00:45:53,360 并不完全满足pset的要求。 546 00:45:53,360 --> 00:46:02,410 pset的要求,第二JPEG文件应该被命名为002,而不是只有2。 547 00:46:02,410 --> 00:46:09,160 所以,当你打印出了名,那么也许你可能要稍微改变了占位符。 548 00:46:09,160 --> 00:46:18,140 >> 有谁还记得我们如何让多余的空格,当我们打印的东西吗? 549 00:46:18,140 --> 00:46:22,530 是啊。 >> [学生]你把3百分号和2之间。 “是的,完美的。 550 00:46:22,530 --> 00:46:25,610 你会在这种情况下,因为我们希望把3 3空间。 551 00:46:25,610 --> 00:46:32,590 %3D可能会给你002.JPG而不是2。 552 00:46:32,590 --> 00:46:40,120 到sprintf函数的第一个参数实际上是一个字符数组, 553 00:46:40,120 --> 00:46:42,520 我们以前所认识的字符串。 554 00:46:42,520 --> 00:46:50,700 那些意志,一种更像是一个临时的存储,只存储所得到的字符串。 555 00:46:50,700 --> 00:46:54,950 你不会真的要处理这个问题,但你需要把它列入。 556 00:46:54,950 --> 00:47:00,710 >> 知道每个文件名的数量,这会占用三个字符, 557 00:47:00,710 --> 00:47:06,770 。JPG,多久这个数组应该是什么? 558 00:47:09,070 --> 00:47:14,310 扔掉了一些。多少个字符的标题,在名称? 559 00:47:18,090 --> 00:47:26,320 因此,3#标签,期间,JPG。 >> [学生] 7。 >> 7。不完全是。 560 00:47:26,320 --> 00:47:32,000 我们要去想,因为我们希望允许空终止。 561 00:47:45,340 --> 00:47:49,730 >> 最后,就是画出来,你会做恢复的过程中, 562 00:47:49,730 --> 00:47:55,420 你有一些开始的信息。 563 00:47:55,420 --> 00:48:02,460 您可以继续,直到你找到一个JPEG文件开始, 564 00:48:02,460 --> 00:48:07,900 而且可以是任一个的两个起始序列。 565 00:48:07,900 --> 00:48:12,510 您继续阅读。在这里每一个斜线代表512个字节。 566 00:48:12,510 --> 00:48:22,630 您继续阅读,继续读,直到你遇到另一个序列。 567 00:48:22,630 --> 00:48:29,790 一旦你有,你结束当前的JPEG - 在这种情况下,它是红色的, 568 00:48:29,790 --> 00:48:31,030 所以你要结束。 569 00:48:31,030 --> 00:48:35,540 你想sprintf的,到您的pset4文件夹的名称, 570 00:48:35,540 --> 00:48:41,580 然后,你要打开一个新的JPEG,然后继续阅读 571 00:48:41,580 --> 00:48:46,370 直到你遇到下。 572 00:48:46,370 --> 00:48:49,040 继续阅读,继续读下去, 573 00:48:49,040 --> 00:48:56,290 然后最后,最终,你会到达终点的文件, 574 00:48:56,290 --> 00:49:00,360 所以你要关闭的最后JPEG您正在使用, 575 00:49:00,360 --> 00:49:08,380 sprintf的,到您的pset4的文件夹,然后看所有的图片,你已经得到了。 576 00:49:08,380 --> 00:49:12,050 这些图片实际上是图片CS50人员, 577 00:49:12,050 --> 00:49:16,430 所以这是在pset的奖金有趣的部分来 578 00:49:16,430 --> 00:49:26,310 是,你在你的小节竞争的图片中找到TFS 579 00:49:26,310 --> 00:49:34,610 并与他们拍照,以证明你已经做了的pset 580 00:49:34,610 --> 00:49:37,030 所以你可以看到,这名工作人员的图片。 581 00:49:37,030 --> 00:49:41,510 那么你拍照的工作人员。有时你会追下来。 582 00:49:41,510 --> 00:49:44,680 也许有些人会尝试离开你。 583 00:49:44,680 --> 00:49:47,320 您与他们拍照。 584 00:49:47,320 --> 00:49:51,190 这是正在进行中。这是不是因为在pset是由于。 585 00:49:51,190 --> 00:49:53,340 在规范中,将公布的截止日期。 586 00:49:53,340 --> 00:49:58,060 然后一起与您的部分,取其部分的大多数图片 587 00:49:58,060 --> 00:50:04,430 与大多数工作人员将获得一个非常可怕的奖品。 588 00:50:04,430 --> 00:50:08,890 这是一种激励得到尽快您的pset4完成 589 00:50:08,890 --> 00:50:10,820 因为这样你可以正事 590 00:50:10,820 --> 00:50:14,570 追捕不同的CS50工作人员。 591 00:50:14,570 --> 00:50:17,500 不过,这不是强制性的,因此,一旦你得到的图片, 592 00:50:17,500 --> 00:50:20,310 那么就大功告成了与pset4。 593 00:50:20,310 --> 00:50:23,970 >> 我完成了演练4,所以,谢谢你的光临。 594 00:50:23,970 --> 00:50:29,330 祝你好运与取证。 [掌声] 595 00:50:29,330 --> 00:50:31,000 [CS50.TV]