1 00:00:00,000 --> 00:00:02,730 [Powered by Google Translate] [SECCIÓN 5: menos cómoda] 2 00:00:02,730 --> 00:00:05,180 [Nate Hardison, Harvard University] 3 00:00:05,180 --> 00:00:08,260 [Esta es CS50.] [CS50.TV] 4 00:00:08,260 --> 00:00:11,690 Así que bienvenidos de nuevo, chicos. 5 00:00:11,690 --> 00:00:16,320 Bienvenidos a la sección 5. 6 00:00:16,320 --> 00:00:20,220 En este punto, después de haber completado prueba 0 y después de haber visto cómo se ha hecho, 7 00:00:20,220 --> 00:00:25,770 esperamos que pueda sentir realmente bien porque yo estaba muy impresionado por los resultados en esta sección. 8 00:00:25,770 --> 00:00:28,050 Para nuestros espectadores en línea, hemos tenido un par de preguntas 9 00:00:28,050 --> 00:00:33,680 sobre los dos últimos problemas en el conjunto de problemas - o en el examen, más bien. 10 00:00:33,680 --> 00:00:39,690 Así que vamos a repasar aquellos muy rápido para que todo el mundo ve lo que pasó 11 00:00:39,690 --> 00:00:45,060 y la forma de ir a través de la solución real en lugar de sólo visualización de la propia solución. 12 00:00:45,060 --> 00:00:50,330 Vamos a ir en el último par de problemas muy rápido, 32 y 33. 13 00:00:50,330 --> 00:00:53,240 Así, de nuevo, de modo que los espectadores en línea se puede ver esto. 14 00:00:53,240 --> 00:00:59,080 >> Si gira a su problema 32, que está en la página 13, 15 00:00:59,080 --> 00:01:02,730 13 de los 16, 32 problema tiene que ver con swaps. 16 00:01:02,730 --> 00:01:05,010 Se trataba de canje de dos números enteros. 17 00:01:05,010 --> 00:01:08,740 Es el problema que habíamos ido un par de veces en la conferencia. 18 00:01:08,740 --> 00:01:13,590 Y aquí, lo que estábamos pidiendo que hagan es una huella de memoria rápida. 19 00:01:13,590 --> 00:01:17,000 Para rellenar los valores de las variables como lo son en la pila 20 00:01:17,000 --> 00:01:20,250 ya que el código pasa a través de esta función swap. 21 00:01:20,250 --> 00:01:24,500 En particular, lo que estamos viendo - Voy a poner esto iPad abajo - 22 00:01:24,500 --> 00:01:29,650 en particular, lo que estamos viendo es la línea número 6 aquí. 23 00:01:29,650 --> 00:01:36,740 Y es el número 6 por sólo contigüidad con el problema anterior. 24 00:01:36,740 --> 00:01:41,720 Lo que quiero hacer es mostrar la etiqueta o el estado de la memoria 25 00:01:41,720 --> 00:01:46,090 como lo es en el momento cuando se ejecuta este número de línea 6, 26 00:01:46,090 --> 00:01:52,540 que es efectivamente un retorno de nuestra función de intercambio aquí. 27 00:01:52,540 --> 00:01:59,450 Si nos desplazamos hasta aquí, hemos visto que las direcciones de todo en la memoria se ha provisto para nosotros. 28 00:01:59,450 --> 00:02:02,540 Esto es muy clave, vamos a volver a ella en un momento. 29 00:02:02,540 --> 00:02:09,240 Y luego aquí abajo en la parte inferior hay un diagrama de poca memoria que nos vamos a referir. 30 00:02:09,240 --> 00:02:12,490 De hecho, he hecho esto en mi iPad. 31 00:02:12,490 --> 00:02:20,720 Así que voy a alternar ida y vuelta entre el iPad y el código esta apenas para la referencia. 32 00:02:20,720 --> 00:02:26,540 >> Vamos a empezar. En primer lugar, vamos a centrarnos en las dos primeras líneas del principal aquí. 33 00:02:26,540 --> 00:02:30,220 Para empezar, vamos a inicializar x e y a 1 a 2. 34 00:02:30,220 --> 00:02:33,040 Así que tenemos dos variables enteras, son a la vez va a ser colocado en la pila. 35 00:02:33,040 --> 00:02:36,050 Vamos a poner un 1 y un 2 en las mismas. 36 00:02:36,050 --> 00:02:43,150 Así que si le doy la vuelta a mi iPad, es de esperar, vamos a ver - 37 00:02:43,150 --> 00:02:48,660 Apple TV mirroring, y ahí vamos. Bien. 38 00:02:48,660 --> 00:02:51,670 Así que si le doy la vuelta a mi iPad, 39 00:02:51,670 --> 00:02:56,220 Quiero inicializar x e y a 1 a 2. 40 00:02:56,220 --> 00:03:00,580 Lo hacemos simplemente escribiendo un 1 en la casilla x 41 00:03:00,580 --> 00:03:07,730 y un 2 en la casilla marcada y. Bastante simple. 42 00:03:07,730 --> 00:03:11,620 Así que ahora vamos a volver a la computadora portátil, a ver qué sucede después. 43 00:03:11,620 --> 00:03:15,810 Así que esta siguiente línea es donde las cosas se ponen difíciles. 44 00:03:15,810 --> 00:03:28,110 Pasamos la dirección de x y de y la dirección como los parámetros a y b para la función swap. 45 00:03:28,110 --> 00:03:32,380 La dirección de xy la dirección de y son cosas que no podemos calcular 46 00:03:32,380 --> 00:03:36,360 sin hacer referencia a estos puntos de bala justo aquí abajo. 47 00:03:36,360 --> 00:03:39,750 Y por suerte, los dos primeros puntos de la bala decirnos exactamente cuáles son las respuestas. 48 00:03:39,750 --> 00:03:44,740 La dirección de x en la memoria es 10, y la dirección de y en la memoria es 14. 49 00:03:44,740 --> 00:03:51,870 Así que estos son los valores que se transmiten en como A y B en lo alto en nuestra función de intercambio. 50 00:03:51,870 --> 00:04:00,760 Así que de nuevo, volviendo a nuestro diagrama, puedo escribir un 10 en una 51 00:04:00,760 --> 00:04:07,400 y un 14 en b. 52 00:04:07,400 --> 00:04:11,610 Ahora, este punto es donde se procede con el canje. 53 00:04:11,610 --> 00:04:14,520 Así que voltear de nuevo a la computadora portátil de nuevo, 54 00:04:14,520 --> 00:04:21,079 vemos que la forma en que el intercambio de obras es que deshacer antes la referencia a y almacenar el resultado en tmp. 55 00:04:21,079 --> 00:04:27,650 De modo que el operador de indirección dice: "Hey. Tratar el contenido de una variable como una dirección. 56 00:04:27,650 --> 00:04:33,830 Ir a lo que está almacenado en esa dirección, y lo cargará. " 57 00:04:33,830 --> 00:04:41,720 ¿Qué se carga de la variable que va a ser almacenado en nuestra variable tmp. 58 00:04:41,720 --> 00:04:45,150 Mover de un tirón de nuevo a la iPad. 59 00:04:45,150 --> 00:04:51,690 Si vamos a abordar 10, se sabe que 10 es la dirección x varible 60 00:04:51,690 --> 00:04:55,480 porque nos dijeron que nuestro punto de bala que la dirección de x en la memoria es de 10. 61 00:04:55,480 --> 00:05:00,180 Así que podemos ir allí, obtener el valor de la misma, que es 1, como podemos ver en nuestro iPad, 62 00:05:00,180 --> 00:05:06,300 y cargar eso en tmp. 63 00:05:06,300 --> 00:05:08,250 Una vez más, esto no es el contenido final. 64 00:05:08,250 --> 00:05:14,350 Vamos a caminar a través y vamos a llegar a nuestro estado final del programa al final. 65 00:05:14,350 --> 00:05:17,210 Pero en este momento, tenemos el valor almacenado en una tmp. 66 00:05:17,210 --> 00:05:19,210 >> Y hay una pregunta rápida por aquí. 67 00:05:19,210 --> 00:05:23,980 [Alexander] Es el operador de indirección - eso es sólo el derecho asterisco al principio de la variable? 68 00:05:23,980 --> 00:05:27,600 Sí >>. De modo que el operador de indirección, ya que voltear hacia atrás para nuestro portátil, una vez más, 69 00:05:27,600 --> 00:05:33,780 es esta estrella justo en frente. 70 00:05:33,780 --> 00:05:37,460 En ese sentido, es - lo que contrasta con el operador de multiplicación 71 00:05:37,460 --> 00:05:42,400 que requiere dos cosas: el operador de indirección es un operador unario. 72 00:05:42,400 --> 00:05:46,130 Sólo se aplica a un valor en lugar de un operador binario, 73 00:05:46,130 --> 00:05:48,810 donde se aplica a dos valores diferentes. 74 00:05:48,810 --> 00:05:52,080 Así que eso es lo que sucede en esta línea. 75 00:05:52,080 --> 00:05:58,390 Cargamos el valor 1 y se almacena en la variable temporal entero. 76 00:05:58,390 --> 00:06:05,800 La siguiente línea, se almacena el contenido de b en - 77 00:06:05,800 --> 00:06:12,630 o, más bien, guardamos los contenidos que se señalan a b en el lugar donde una está apuntando. 78 00:06:12,630 --> 00:06:17,690 Si analizamos este de derecha a izquierda, vamos a eliminar la referencia b, 79 00:06:17,690 --> 00:06:23,580 vamos a abordar 14, vamos a agarrar el entero que está allí, 80 00:06:23,580 --> 00:06:26,900 y luego vamos a ir a la dirección 10, 81 00:06:26,900 --> 00:06:34,240 y vamos a lanzar el resultado de eliminar la referencia de b en ese espacio. 82 00:06:34,240 --> 00:06:40,080 Volteando a nuestro iPad, donde podemos hacer esto un poco más concreto, 83 00:06:40,080 --> 00:06:44,070 puede ser que ayude si escribo números en todas las direcciones aquí. 84 00:06:44,070 --> 00:06:53,820 Así que sabemos que en y, estamos en la dirección 14, x está en la dirección 10. 85 00:06:53,820 --> 00:07:00,180 Cuando empezamos a b, b dereference, vamos a tomar el valor 2. 86 00:07:00,180 --> 00:07:08,320 Vamos a coger este valor debido a que es el valor que vive en la dirección 14. 87 00:07:08,320 --> 00:07:15,700 Y vamos a ponerlo en la variable que vive en la dirección 10, 88 00:07:15,700 --> 00:07:19,160 que está ahí, que corresponde a nuestros variable x. 89 00:07:19,160 --> 00:07:21,810 Así que podemos hacer un poco de sobrescribir aquí 90 00:07:21,810 --> 00:07:35,380 donde nos deshacemos de nuestra 1 y en su lugar escribir un 2. 91 00:07:35,380 --> 00:07:39,560 Así que todo está bien y es bueno en el mundo, a pesar de que hemos x sobrescritos ahora. 92 00:07:39,560 --> 00:07:44,890 Hemos almacenado antiguo valor de x en la variable tmp. 93 00:07:44,890 --> 00:07:50,210 Así podemos completar el intercambio con la línea siguiente. 94 00:07:50,210 --> 00:07:53,030 Mover de un tirón de nuevo a nuestro portátil. 95 00:07:53,030 --> 00:07:58,150 Ahora todo lo que queda es tomar el contenido de nuestra variable entera temporal 96 00:07:58,150 --> 00:08:05,630 y los almacena en la variable que vive en la dirección que b está sosteniendo. 97 00:08:05,630 --> 00:08:10,230 Así que vamos a eliminar la referencia b eficaz para conseguir el acceso a la variable 98 00:08:10,230 --> 00:08:14,340 es decir, en la dirección que b tiene en él, 99 00:08:14,340 --> 00:08:19,190 y vamos a meter el valor que está llevando a cabo tmp en ella. 100 00:08:19,190 --> 00:08:23,280 Voltear de nuevo al iPad una vez más. 101 00:08:23,280 --> 00:08:31,290 Puedo borrar este valor aquí, 2, 102 00:08:31,290 --> 00:08:41,010 y en su lugar vamos a copiar la derecha 1 en él. 103 00:08:41,010 --> 00:08:43,059 A continuación, la siguiente línea que se ejecuta, por supuesto - 104 00:08:43,059 --> 00:08:47,150 si tiramos de nuevo a la computadora portátil - es este el punto 6, 105 00:08:47,150 --> 00:08:52,500 que es el punto en el que queríamos tener nuestro diagrama llenada completamente. 106 00:08:52,500 --> 00:08:58,940 Así que voltear de nuevo al iPad una vez más, sólo para que pueda ver el diagrama completo, 107 00:08:58,940 --> 00:09:06,610 se puede ver que tenemos un 10 en una, un 14 en b, a 1 en tmp, un 2 en x, y un 1 en y. 108 00:09:06,610 --> 00:09:11,000 ¿Hay alguna pregunta acerca de esto? 109 00:09:11,000 --> 00:09:14,640 ¿Esto tiene más sentido, de haber caminado a través de él? 110 00:09:14,640 --> 00:09:24,850 Hacer menos sentido? Esperemos que no. Bien. 111 00:09:24,850 --> 00:09:28,230 >> Los punteros son un tema muy delicado. 112 00:09:28,230 --> 00:09:33,420 Uno de los chicos con los que trabajamos tiene un dicho muy común: 113 00:09:33,420 --> 00:09:36,590 "Para entender los punteros, primero hay que entender punteros". 114 00:09:36,590 --> 00:09:40,530 Lo que creo que es muy cierto. Sin embargo, toma algún tiempo para acostumbrarse a ella. 115 00:09:40,530 --> 00:09:45,360 Dibujo muchas fotos, sorteo de diagramas de memoria como ésta son muy útiles, 116 00:09:45,360 --> 00:09:49,480 y después de caminar a través del ejemplo tras ejemplo tras ejemplo, 117 00:09:49,480 --> 00:09:54,450 que va a empezar a tener sentido un poco más y un poco más de sentido y un poco más de sentido. 118 00:09:54,450 --> 00:10:01,560 Finalmente, un día, tendrás todo completamente dominado. 119 00:10:01,560 --> 00:10:13,800 Cualquier pregunta antes de pasar al siguiente problema? Está bien. 120 00:10:13,800 --> 00:10:18,840 Así que dar la vuelta de nuevo a la computadora portátil. 121 00:10:18,840 --> 00:10:23,300 El siguiente problema que tenemos es el problema número 33 en el archivo I / O. 122 00:10:23,300 --> 00:10:26,350 Zoom sobre esto un poco. 123 00:10:26,350 --> 00:10:28,710 Problema 33 - ¿Sí? 124 00:10:28,710 --> 00:10:32,110 >> [Daniel] Acabo de tener una pregunta rápida. Esta estrella, o el asterisco, 125 00:10:32,110 --> 00:10:35,590 se llama eliminación de referencias cuando se utiliza un asterisco antes. 126 00:10:35,590 --> 00:10:38,820 ¿Cómo se llama cuando se utiliza el signo & antes? 127 00:10:38,820 --> 00:10:43,140 >> El signo & antes es el operador de dirección. 128 00:10:43,140 --> 00:10:45,880 Así que vamos a pasar de regreso. 129 00:10:45,880 --> 00:10:49,310 Oops. Estoy en el modo de zoom, así que no puede desplazarse. 130 00:10:49,310 --> 00:10:52,780 Si nos fijamos en el código muy rápido aquí, 131 00:10:52,780 --> 00:10:54,980 de nuevo, lo mismo sucedía. 132 00:10:54,980 --> 00:10:59,180 Si nos fijamos en el código aquí mismo, en esta línea donde hacemos el llamado a cambiar, 133 00:10:59,180 --> 00:11:10,460 el signo es sólo decir "obtener la dirección en que vive la variable x." 134 00:11:10,460 --> 00:11:14,460 Cuando el compilador compila el código, 135 00:11:14,460 --> 00:11:20,590 tiene que físicamente marcar un lugar en la memoria para todas sus variables para vivir. 136 00:11:20,590 --> 00:11:24,910 Y así, lo que el compilador puede hacer una vez que se compila todo, 137 00:11:24,910 --> 00:11:31,110 lo sabe "Oh, puse x en la dirección 10. Pongo y en la dirección 14." 138 00:11:31,110 --> 00:11:34,640 A continuación, puede rellenar estos valores para usted. 139 00:11:34,640 --> 00:11:44,740 Así que usted puede - puede entonces pasar esto y pass & y adentro también. 140 00:11:44,740 --> 00:11:50,730 Estos chicos obtener la dirección, sino que también, cuando se pasa a la función de intercambio, 141 00:11:50,730 --> 00:11:55,690 este tipo de información, esta * int aquí, le dice al compilador, 142 00:11:55,690 --> 00:12:01,350 "Está bien, vamos a estar interpretando esta dirección como una dirección de una variable entera". 143 00:12:01,350 --> 00:12:05,900 Como una dirección de un entero, que es diferente de la dirección de una variable de carácter 144 00:12:05,900 --> 00:12:09,930 porque un int ocupa, en una máquina de 32-bit, toma hasta 4 bytes de espacio, 145 00:12:09,930 --> 00:12:13,310 mientras que un personaje sólo ocupa 1 byte de espacio. 146 00:12:13,310 --> 00:12:17,310 Así que es importante saber también lo que es - lo que vive, qué tipo de valor 147 00:12:17,310 --> 00:12:20,340 vive en la dirección que he pasado pulg 148 00:12:20,340 --> 00:12:22,020 O la dirección que usted está tratando. 149 00:12:22,020 --> 00:12:29,020 De esa manera, usted sabe cuántos bytes de información para cargar realidad de la memoria RAM. 150 00:12:29,020 --> 00:12:31,780 Y entonces, sí, este operador para deshacer referencias, como si estuvieras pidiendo, 151 00:12:31,780 --> 00:12:37,200 va y se accede a la información en una dirección particular. 152 00:12:37,200 --> 00:12:42,820 Por lo que dice, con esta variable a aquí, tratar los contenidos de una como dirección, 153 00:12:42,820 --> 00:12:47,880 ir a esa dirección, y extraer, cargar en el procesador, la carga en un registro 154 00:12:47,880 --> 00:12:56,340 los valores reales o de los contenidos que viven en ese domicilio. 155 00:12:56,340 --> 00:12:59,620 Algo más preguntas? Estas son buenas preguntas. 156 00:12:59,620 --> 00:13:01,650 Es un montón de nueva terminología también. 157 00:13:01,650 --> 00:13:09,800 Es también una especie de funky, y viendo * y en diferentes lugares. 158 00:13:09,800 --> 00:13:13,180 >> Está bien. 159 00:13:13,180 --> 00:13:18,530 Así que volvemos al problema de 33 años, presentar I / O. 160 00:13:18,530 --> 00:13:22,540 Este fue uno de esos problemas que creo que un par de cosas sucedieron. 161 00:13:22,540 --> 00:13:25,400 Uno, que es un tema bastante nuevo. 162 00:13:25,400 --> 00:13:30,590 Se presentó muy pronto antes de la prueba, 163 00:13:30,590 --> 00:13:33,400 y entonces yo creo que fue algo así como uno de esos problemas verbales de matemáticas 164 00:13:33,400 --> 00:13:39,720 donde te dan un montón de información, pero en realidad no terminan encima de tener que usar un montón de él. 165 00:13:39,720 --> 00:13:44,060 La primera parte de este problema se describe qué es un archivo CSV. 166 00:13:44,060 --> 00:13:50,620 Ahora, un archivo CSV, de acuerdo con la descripción, es un archivo de valores separados por comas. 167 00:13:50,620 --> 00:13:55,300 La razón de que estos son para nada interesante, y la razón por la que nunca los utilizan, 168 00:13:55,300 --> 00:14:00,800 Es decir, porque, ¿cuántos de ustedes han utilizado alguna vez cosas como Excel? 169 00:14:00,800 --> 00:14:03,240 Figura mayoría de ustedes, probablemente, o va a utilizar en algún momento de su vida. 170 00:14:03,240 --> 00:14:06,430 Vamos a usar algo como Excel. 171 00:14:06,430 --> 00:14:10,940 Con el fin de obtener los datos de una hoja de cálculo de Excel o hacer cualquier tipo de tratamiento efectuado con ella, 172 00:14:10,940 --> 00:14:17,240 si quieres escribir un programa en C o programa en Python, un programa Java, 173 00:14:17,240 --> 00:14:20,070 para hacer frente a los datos que haya almacenado ahí, 174 00:14:20,070 --> 00:14:23,170 una de las formas más comunes para sacarlo está en un archivo CSV. 175 00:14:23,170 --> 00:14:26,850 Y usted puede abrir Excel y cuando vas a la opción 'Guardar como' diálogo, 176 00:14:26,850 --> 00:14:32,840 usted puede salir un archivo CSV real. 177 00:14:32,840 --> 00:14:35,890 >> Es útil saber cómo lidiar con estas cosas. 178 00:14:35,890 --> 00:14:42,010 La forma en que funciona es que es similar a - Quiero decir, es esencialmente imitando una hoja de cálculo, 179 00:14:42,010 --> 00:14:47,590 donde, como vemos aquí, en la parte más a la izquierda, 180 00:14:47,590 --> 00:14:49,910 tenemos todos los apellidos. 181 00:14:49,910 --> 00:14:54,670 Así que tenemos Malan, a continuación, Hardison, y luego Bowden, MacWilliam, y luego Chan. 182 00:14:54,670 --> 00:14:59,470 Todos los apellidos. Y luego una coma separa los apellidos de los nombres de pila. 183 00:14:59,470 --> 00:15:02,970 David, Nate, Rob, Tommy, y Zamyla. 184 00:15:02,970 --> 00:15:06,850 Siempre mezclar Robby y Tom. 185 00:15:06,850 --> 00:15:10,940 Y entonces, por fin, la tercera columna es la dirección de correo electrónico. 186 00:15:10,940 --> 00:15:18,500 Una vez que entiendas eso, el resto del programa es bastante sencillo de implementar. 187 00:15:18,500 --> 00:15:23,850 Lo que hemos hecho con el fin de imitar la estructura misma de nuestro programa en C 188 00:15:23,850 --> 00:15:27,510 es que hemos utilizado una estructura. 189 00:15:27,510 --> 00:15:30,520 Vamos a empezar a jugar con ellos un poco más también. 190 00:15:30,520 --> 00:15:35,790 Los vimos en el primer pedacito pequeño problema en el conjunto 3, cuando se trataba de los diccionarios. 191 00:15:35,790 --> 00:15:40,290 Pero esta estructura personal almacena un apellido, un nombre, y un correo electrónico. 192 00:15:40,290 --> 00:15:44,500 Al igual que nuestro archivo CSV estaba almacenando. 193 00:15:44,500 --> 00:15:47,950 Así que esto es sólo la conversión de un formato a otro. 194 00:15:47,950 --> 00:15:54,630 Tenemos que convertir, en este caso, una estructura personal en una línea, 195 00:15:54,630 --> 00:15:59,060 una línea separada por comas, así como así. 196 00:15:59,060 --> 00:16:01,500 ¿Eso tiene sentido? Ustedes han tomado el examen, 197 00:16:01,500 --> 00:16:07,680 así que me imagino que por lo menos han tenido tiempo para pensar en esto. 198 00:16:07,680 --> 00:16:16,410 >> En la función de contratación, el problema pide que tomemos en - nos volveremos a ampliar esto un poco poco - 199 00:16:16,410 --> 00:16:22,480 tomar en una estructura de personal, una estructura de personal, con el nombre de s, 200 00:16:22,480 --> 00:16:30,900 y añadir su contenido a nuestro archivo staff.csv. 201 00:16:30,900 --> 00:16:34,230 Resulta que este es bastante sencillo de usar. 202 00:16:34,230 --> 00:16:37,430 Vamos a clase de jugar con estas funciones un poco más hoy en día. 203 00:16:37,430 --> 00:16:44,510 Pero en este caso, la función fprintf es realmente la clave. 204 00:16:44,510 --> 00:16:51,960 Así que con fprintf, podemos imprimir, al igual que ustedes han estado usando printf este término entero. 205 00:16:51,960 --> 00:16:55,050 Puede printf una línea en un archivo. 206 00:16:55,050 --> 00:16:59,030 Así que en lugar de sólo hacer la llamada printf habitual donde se le da la cadena de formato 207 00:16:59,030 --> 00:17:05,380 y luego cambia todas las variables con los siguientes argumentos, 208 00:17:05,380 --> 00:17:11,290 con fprintf, su primer argumento es en cambio el archivo que desea escribir. 209 00:17:11,290 --> 00:17:21,170 Si fuéramos a ver esto en el aparato, por ejemplo, el hombre fprintf, 210 00:17:21,170 --> 00:17:25,980 podemos ver la diferencia entre printf y fprintf. 211 00:17:25,980 --> 00:17:28,960 Voy a ampliar aquí un poco. 212 00:17:28,960 --> 00:17:33,140 Así que con printf, le damos una cadena de formato y, a continuación los argumentos posteriores 213 00:17:33,140 --> 00:17:37,580 son todas las variables para el reemplazo o sustitución en nuestra cadena de formato. 214 00:17:37,580 --> 00:17:47,310 Mientras que con fprintf, el primer argumento es precisamente esta * archivo llamado un arroyo. 215 00:17:47,310 --> 00:17:51,800 >> Volviendo aquí a nuestros contratos de alquiler, 216 00:17:51,800 --> 00:17:54,550 ya tenemos nuestro flujo * archivo abierto para nosotros. 217 00:17:54,550 --> 00:17:57,810 Eso es lo primero que hace esta línea, se abre el archivo staff.csv, 218 00:17:57,810 --> 00:18:01,690 lo abre en modo append, y es todo lo que nos queda por hacer 219 00:18:01,690 --> 00:18:08,640 escribir la estructura de la plantilla en el archivo. 220 00:18:08,640 --> 00:18:10,870 Y, vamos a ver, ¿me quieres usar el iPad? 221 00:18:10,870 --> 00:18:17,900 Voy a utilizar el iPad. Tenemos vacío - Vamos a poner esto sobre la mesa para que yo pueda escribir un poco mejor - 222 00:18:17,900 --> 00:18:33,680 anular el alquiler y que se necesita en un argumento, una estructura de personal llamado s. 223 00:18:33,680 --> 00:18:44,120 Got nuestras llaves, tenemos nuestro archivo llamado * archivo, 224 00:18:44,120 --> 00:18:48,380 tenemos nuestra línea fopen dado a nosotros, 225 00:18:48,380 --> 00:18:51,890 y yo sólo voy a escribir en forma de puntos, ya que ya está en el pedia. 226 00:18:51,890 --> 00:19:00,530 Y luego, en nuestra línea siguiente, vamos a hacer una llamada a fprintf 227 00:19:00,530 --> 00:19:03,700 y vamos a pasar en el archivo que desea imprimir, 228 00:19:03,700 --> 00:19:10,290 y luego nuestro formato de cadena, que - 229 00:19:10,290 --> 00:19:14,300 Voy a dejar que ustedes me dicen lo que parece. 230 00:19:14,300 --> 00:19:20,500 ¿Y tú, Stella? ¿Sabes lo que la primera parte de la cadena de formato se parece? 231 00:19:20,500 --> 00:19:24,270 [Stella] Yo no estoy seguro. >> No dude en preguntar Jimmy. 232 00:19:24,270 --> 00:19:27,690 ¿Sabe usted, Jimmy? 233 00:19:27,690 --> 00:19:31,000 [Jimmy] ¿Podría ser sólo pasado? No se. No estoy del todo seguro. 234 00:19:31,000 --> 00:19:39,020 >> Okay. ¿Qué tal, ¿alguien obtener esta correcto en el examen? 235 00:19:39,020 --> 00:19:41,770 No. Está bien. 236 00:19:41,770 --> 00:19:47,920 Resulta que aquí lo único que tenemos que hacer es que queremos que cada parte de nuestra estructura de personal 237 00:19:47,920 --> 00:19:53,290 para ser impreso como una cadena en nuestro archivo. 238 00:19:53,290 --> 00:19:59,900 Nos limitamos a usar el personaje de sustitución de cadenas en tres ocasiones diferentes, porque tenemos un apellido 239 00:19:59,900 --> 00:20:07,160 seguido de coma, luego de un primer nombre seguido de una coma, 240 00:20:07,160 --> 00:20:12,430 y, finalmente, la dirección de correo electrónico que es seguido - que no es 241 00:20:12,430 --> 00:20:15,140 montar en mi pantalla - pero es seguido por un carácter de nueva línea. 242 00:20:15,140 --> 00:20:20,060 Así que voy a escribir justo ahí abajo. 243 00:20:20,060 --> 00:20:23,560 Y luego, después de nuestra cadena de formato, 244 00:20:23,560 --> 00:20:27,880 sólo tenemos las sustituciones, que se accede mediante la notación de puntos 245 00:20:27,880 --> 00:20:31,370 que vimos en el boletín de problemas 3. 246 00:20:31,370 --> 00:20:48,820 Podemos utilizar s.last, s.first y s.email 247 00:20:48,820 --> 00:20:58,990 para sustituir en esos tres valores en nuestra cadena de formato. 248 00:20:58,990 --> 00:21:06,190 Entonces, ¿cómo te fue? Tiene sentido? 249 00:21:06,190 --> 00:21:09,700 ¿Sí? No? Posiblemente? Bien. 250 00:21:09,700 --> 00:21:14,180 >> La última cosa que hacemos después de haber impreso y después de que hemos abierto nuestro archivo: 251 00:21:14,180 --> 00:21:17,370 cada vez que hemos abierto un archivo, siempre tenemos que recordar para cerrarla. 252 00:21:17,370 --> 00:21:19,430 Porque de lo contrario vamos a terminar la filtración de la memoria, 253 00:21:19,430 --> 00:21:22,500 utilizando hasta descriptores de fichero. 254 00:21:22,500 --> 00:21:25,950 Así que para cerrar, que funcionan usamos? Daniel? 255 00:21:25,950 --> 00:21:30,120 [Daniel] fclose? >> Fclose, exactamente. 256 00:21:30,120 --> 00:21:37,520 Así que la última parte de este problema consistía en cerrar correctamente el archivo, utilizando la función fclose, 257 00:21:37,520 --> 00:21:40,370 que sólo se parece a eso. 258 00:21:40,370 --> 00:21:43,880 No está loco. 259 00:21:43,880 --> 00:21:46,990 Cool. 260 00:21:46,990 --> 00:21:49,520 Así que eso es problema 33 en el concurso. 261 00:21:49,520 --> 00:21:52,480 Tendremos archivo definitivamente más I / O viene. 262 00:21:52,480 --> 00:21:55,130 Vamos a hacer un poco más en la conferencia de hoy, o en la sección de hoy, 263 00:21:55,130 --> 00:22:01,710 porque eso es lo que va a constituir la mayor parte de este conjunto de procesadores próximo. 264 00:22:01,710 --> 00:22:05,020 Vamos a pasar de la prueba en este punto. ¿Sí? 265 00:22:05,020 --> 00:22:10,880 >> [Charlotte]] ¿Por qué fclose (archivo) en vez de fclose (staff.csv)? 266 00:22:10,880 --> 00:22:19,100 >> Ah. Porque resulta que - por lo que la pregunta, que es un grande, 267 00:22:19,100 --> 00:22:27,800 Por eso, cuando escribimos fclose, ¿estamos escribiendo fclose (archivo) estrella variable 268 00:22:27,800 --> 00:22:33,680 en contraposición al nombre de archivo, staff.csv? ¿Es eso correcto? Si. 269 00:22:33,680 --> 00:22:39,570 Así que vamos a echar un vistazo. Si vuelvo a mi ordenador portátil, 270 00:22:39,570 --> 00:22:45,040 y echemos un vistazo a la función fclose. 271 00:22:45,040 --> 00:22:51,460 Así que la función fclose cierra un arroyo y que se necesita en el puntero al flujo que queremos cerrar, 272 00:22:51,460 --> 00:22:57,010 en comparación con el nombre real del archivo que desea cerrar. 273 00:22:57,010 --> 00:23:01,620 Y es que detrás de las escenas, cuando usted hace una llamada a fopen, 274 00:23:01,620 --> 00:23:12,020 cuando se abre un archivo, en realidad estás asignación de memoria para almacenar la información sobre el archivo. 275 00:23:12,020 --> 00:23:16,380 Así que tienes puntero del archivo que contiene información sobre el archivo, 276 00:23:16,380 --> 00:23:23,080 tal como está abierto, su tamaño, en la que se encuentran actualmente en el archivo, 277 00:23:23,080 --> 00:23:29,100 de modo que usted puede hacer que la lectura y la escritura llamadas a ese lugar en particular dentro del archivo. 278 00:23:29,100 --> 00:23:38,060 Se termina de cerrar el puntero en lugar de cerrar el nombre del archivo. 279 00:23:38,060 --> 00:23:48,990 >> ¿Sí? [Daniel] Así que con el fin de utilizar de alquiler, ¿diría usted - ¿cómo obtener la entrada del usuario? 280 00:23:48,990 --> 00:23:53,830 ¿Tiene fprintf actuar como GetString en el sentido de que sólo voy a esperar a que la entrada del usuario 281 00:23:53,830 --> 00:23:57,180 y le pedirá que escriba esto - o esperar a que escriba estas tres cosas? 282 00:23:57,180 --> 00:24:00,480 ¿O es necesario utilizar algo de implementar alquiler? 283 00:24:00,480 --> 00:24:04,100 Sí >>. Así que no estamos - la pregunta fue, ¿cómo hacemos para que la entrada del usuario 284 00:24:04,100 --> 00:24:09,220 con el fin de implementar alquiler? Y lo que tenemos aquí es el llamador de alquiler, 285 00:24:09,220 --> 00:24:17,690 aprobada en esta estructura personal con todos los datos almacenados en la estructura ya. 286 00:24:17,690 --> 00:24:22,990 Así fprintf es capaz de escribir sólo los datos directamente en el archivo. 287 00:24:22,990 --> 00:24:25,690 No es necesario esperar a que el usuario. 288 00:24:25,690 --> 00:24:32,110 El usuario ya está dado por la entrada correctamente poniendo en esta estructura de personal. 289 00:24:32,110 --> 00:24:36,510 Y las cosas, por supuesto, se rompería si alguno de los punteros eran nulas, 290 00:24:36,510 --> 00:24:40,370 por lo que desplazarse de nuevo hasta aquí y nos fijamos en nuestra estructura. 291 00:24:40,370 --> 00:24:43,640 Tenemos string apellido, nombre, dirección de correo electrónico cadena. 292 00:24:43,640 --> 00:24:48,530 Ahora sabemos que todos los que en realidad, bajo el capó, son variables char *. 293 00:24:48,530 --> 00:24:53,470 Que puede o no puede estar apuntando a null. 294 00:24:53,470 --> 00:24:55,800 Pueden estar apuntando a la memoria en el montón, 295 00:24:55,800 --> 00:24:59,650 tal memoria en la pila. 296 00:24:59,650 --> 00:25:04,580 Realmente no lo sé, pero, si alguno de estos indicadores es nulo o no válido 297 00:25:04,580 --> 00:25:08,120 que que definitivamente va a estrellar nuestra función de contratación. 298 00:25:08,120 --> 00:25:11,050 Eso era algo que estaba un poco más allá del alcance del examen. 299 00:25:11,050 --> 00:25:16,440 No vamos a tener que preocuparse por eso. 300 00:25:16,440 --> 00:25:22,170 Grande. Bien. Así que pasar de la prueba. 301 00:25:22,170 --> 00:25:25,760 >> Vamos a cerrar este tipo, y vamos a ver pset 4. 302 00:25:25,760 --> 00:25:34,700 Así que si ustedes mirar las especificaciones conjunto de procesadores, una vez que se puede acceder a ella, cs50.net/quizzes, 303 00:25:34,700 --> 00:25:42,730 vamos a ir a través de algunos de los problemas de la sección actual. 304 00:25:42,730 --> 00:25:52,240 Estoy desplazamiento hacia abajo - sección de preguntas comienza en la tercera página de la especificación de conjunto de procesadores. 305 00:25:52,240 --> 00:25:57,800 Y lo primero que pide para ir a ver el corto en la reorientación y tuberías. 306 00:25:57,800 --> 00:26:02,820 Lo cual era una especie de fresco a corto, te muestra algunos trucos nuevos, frescos línea de comandos que se pueden utilizar. 307 00:26:02,820 --> 00:26:06,050 Y luego tenemos algunas preguntas para usted también. 308 00:26:06,050 --> 00:26:10,860 Esta primera pregunta acerca de los arroyos, para que printf escribe de forma predeterminada, 309 00:26:10,860 --> 00:26:15,920 que tipo de tocado un poco hace un momento. 310 00:26:15,920 --> 00:26:22,380 Esta fprintf que estábamos discutiendo toma en un arroyo archivo * como argumento. 311 00:26:22,380 --> 00:26:26,580 fclose toma en un flujo de archivo *, así, 312 00:26:26,580 --> 00:26:32,660 y el valor devuelto por fopen le da una corriente * archivo también. 313 00:26:32,660 --> 00:26:36,060 La razón por la que no hemos visto antes, cuando los hemos tratado con printf 314 00:26:36,060 --> 00:26:39,450 es porque printf tiene una secuencia predeterminada. 315 00:26:39,450 --> 00:26:41,810 Y la corriente de defecto a los que se escribe 316 00:26:41,810 --> 00:26:45,190 podrás conocer en el corto plazo. 317 00:26:45,190 --> 00:26:50,080 Así que definitivamente echar un vistazo. 318 00:26:50,080 --> 00:26:53,010 >> En la sección de hoy, vamos a hablar un poco acerca de GDB, 319 00:26:53,010 --> 00:26:57,720 ya que cuanto más familiarizado esté con él, la práctica más que se obtiene con ella, 320 00:26:57,720 --> 00:27:01,390 el mejor preparado estará para cazar a los insectos en realidad en su propio código. 321 00:27:01,390 --> 00:27:05,540 Esto acelera el proceso de depuración tremendamente. 322 00:27:05,540 --> 00:27:09,230 Así mediante el uso de printf, cada vez que haces eso tienes que volver a compilar el código, 323 00:27:09,230 --> 00:27:13,000 tienes que correr de nuevo, a veces hay que mover la llamada printf alrededor, 324 00:27:13,000 --> 00:27:17,100 comentar código, sólo se necesita un tiempo. 325 00:27:17,100 --> 00:27:20,850 Nuestro objetivo es tratar de convencerlos de que con GDB, usted puede esencialmente 326 00:27:20,850 --> 00:27:26,810 printf nada en cualquier punto de su código y usted nunca tendrá que volver a compilar. 327 00:27:26,810 --> 00:27:35,120 Usted nunca tiene que iniciar y mantener adivinando dónde printf siguiente. 328 00:27:35,120 --> 00:27:40,910 Lo primero que debe hacer es copiar esta línea y obtener el código de sección de la web. 329 00:27:40,910 --> 00:27:47,530 Estoy copiando esta línea de código que dice: "http://cdn.cs50.net wget". 330 00:27:47,530 --> 00:27:49,510 Yo lo voy a copiar. 331 00:27:49,510 --> 00:27:55,950 Voy a ir a mi aparato, alejar para que pueda ver lo que estoy haciendo, 332 00:27:55,950 --> 00:28:01,890 pegarlo allí, y cuando pulse la tecla Enter, este comando wget literalmente es una web conseguirlo. 333 00:28:01,890 --> 00:28:06,210 Va a bajar el archivo fuera de la Internet, 334 00:28:06,210 --> 00:28:11,790 y va a guardarlo en el directorio actual. 335 00:28:11,790 --> 00:28:21,630 Ahora bien, si enumero mi directorio actual se puede ver que tengo el archivo section5.zip bien ahí. 336 00:28:21,630 --> 00:28:25,260 La manera de tratar con ese tipo es que descomprimirlo, 337 00:28:25,260 --> 00:28:27,650 que se puede hacer en la línea de comandos, al igual que este. 338 00:28:27,650 --> 00:28:31,880 Section5.zip. 339 00:28:31,880 --> 00:28:36,980 Eso lo descomprima, cree la carpeta para mí, 340 00:28:36,980 --> 00:28:40,410 inflar todo el contenido, los puso allí. 341 00:28:40,410 --> 00:28:47,410 Así que ahora puedo ir a mi sección 5 directorio con el comando cd. 342 00:28:47,410 --> 00:28:58,310 Limpiar la pantalla con clara. Así que limpiar la pantalla. 343 00:28:58,310 --> 00:29:02,280 Ahora tengo un terminal limpio y agradable de manejar. 344 00:29:02,280 --> 00:29:06,200 >> Ahora bien, si una lista de todos los archivos que aparecen en este directorio, 345 00:29:06,200 --> 00:29:12,270 veis que yo tengo cuatro archivos: buggy1, buggy2, buggy3 y buggy4. 346 00:29:12,270 --> 00:29:16,180 También tengo los archivos de C correspondiente.. 347 00:29:16,180 --> 00:29:20,400 No vamos a mirar los archivos. C por ahora. 348 00:29:20,400 --> 00:29:24,140 En su lugar, vamos a usarlas cuando abrimos GDB. 349 00:29:24,140 --> 00:29:28,220 Nos hemos mantenido en torno a lo que tenemos acceso al código fuente real cuando estamos usando GDB, 350 00:29:28,220 --> 00:29:32,740 pero el objetivo de esta parte de la sección es juguetear un poco con GDB 351 00:29:32,740 --> 00:29:40,370 y ver cómo podemos utilizarlo para averiguar lo que va mal con cada uno de estos cuatro programas con errores. 352 00:29:40,370 --> 00:29:43,380 Así que sólo vamos a por el cuarto muy rápido, 353 00:29:43,380 --> 00:29:47,000 y yo voy a pedir a alguien para ejecutar uno de los programas con errores, 354 00:29:47,000 --> 00:29:54,730 y luego vamos a ir como un grupo a través del BGF, y vamos a ver qué podemos hacer para arreglar estos programas, 355 00:29:54,730 --> 00:29:58,460 o identificar al menos lo que va mal en cada uno de ellos. 356 00:29:58,460 --> 00:30:04,760 Vamos a empezar por aquí con Daniel. ¿Va a correr buggy1? Vamos a ver qué pasa. 357 00:30:04,760 --> 00:30:09,470 [Daniel] Se dice que hay un error de aplicación. Sí >>. Exactamente. 358 00:30:09,470 --> 00:30:12,460 Así que si me quedo buggy1, me sale un error seg. 359 00:30:12,460 --> 00:30:16,210 En este punto, yo podría ir y abrir buggy1.c, 360 00:30:16,210 --> 00:30:19,450 tratar de averiguar lo que va mal, 361 00:30:19,450 --> 00:30:22,000 pero una de las cosas más desagradables acerca de este error de errores seg 362 00:30:22,000 --> 00:30:27,610 es que no te dice en qué línea del programa de las cosas realmente salió mal y se rompió. 363 00:30:27,610 --> 00:30:29,880 De alguna manera tenemos que mirar el código 364 00:30:29,880 --> 00:30:33,990 y averiguar mediante conjeturas y comprobar o printf para ver lo que va mal. 365 00:30:33,990 --> 00:30:37,840 Una de las mejores cosas acerca de GDB es que es muy, muy fácil 366 00:30:37,840 --> 00:30:42,170 para averiguar la línea a la que el programa se bloquea. 367 00:30:42,170 --> 00:30:46,160 Está totalmente digno de él para usarlo, aunque sólo sea por eso. 368 00:30:46,160 --> 00:30:56,190 Así que para arrancar GDB, tipo I GDB, y luego le doy la ruta de acceso al archivo ejecutable que desea ejecutar. 369 00:30:56,190 --> 00:31:01,960 Aquí estoy escribiendo gdb ./buggy1. 370 00:31:01,960 --> 00:31:06,600 Pulse Enter. Me da toda esta información de derechos de autor, 371 00:31:06,600 --> 00:31:13,000 y aquí usted verá esta línea que dice: "Lectura de símbolos / home / 372 00:31:13,000 --> 00:31:17,680 jharvard/section5/buggy1 ". 373 00:31:17,680 --> 00:31:22,060 Y si todo va bien, verás que imprima un mensaje parecido a éste. 374 00:31:22,060 --> 00:31:25,500 Se va a leer los símbolos, que va a decir "Estoy leyendo los símbolos de su archivo ejecutable" 375 00:31:25,500 --> 00:31:29,900 y entonces tendrá este "hecho" mensaje aquí. 376 00:31:29,900 --> 00:31:35,410 Si ves alguna otra variante de esto, o ver que no podía encontrar los símbolos 377 00:31:35,410 --> 00:31:41,460 o algo por el estilo, lo que quiere decir es que usted no haya compilado su ejecutable correctamente. 378 00:31:41,460 --> 00:31:49,980 Al compilar programas para su uso con GDB, tenemos que usar esa bandera especial-g, 379 00:31:49,980 --> 00:31:54,540 y eso se hace por defecto si compila los programas, simplemente tecleando make 380 00:31:54,540 --> 00:31:59,320 o hacer buggy o hacer recuperar, nada de eso. 381 00:31:59,320 --> 00:32:07,800 Pero si estás compilando manualmente con Clang, entonces usted tendrá que ir y que incluyen-g. 382 00:32:07,800 --> 00:32:10,310 >> En este punto, ahora que tenemos nuestro GDB del sistema, 383 00:32:10,310 --> 00:32:12,310 que es muy simple de ejecutar el programa. 384 00:32:12,310 --> 00:32:19,740 Podemos escribir run, o simplemente podemos escribir r. 385 00:32:19,740 --> 00:32:22,820 La mayoría de los comandos de GDB puede ser abreviado. 386 00:32:22,820 --> 00:32:25,940 Por lo general, a sólo una o unas letras de un par, lo cual es bastante agradable. 387 00:32:25,940 --> 00:32:30,980 Así Saad, si escribe r y presione Enter, ¿qué pasa? 388 00:32:30,980 --> 00:32:39,390 [Saad] Tengo SIGSEGV, fallo de segmentación, y entonces todo este galimatías. 389 00:32:39,390 --> 00:32:43,650 Sí >>. 390 00:32:43,650 --> 00:32:47,990 Como estamos viendo en la pantalla en este momento, y como dijo Saad, 391 00:32:47,990 --> 00:32:53,430 cuando tecleamos carrera o r y pulse la tecla Enter, se sigue recibiendo el mismo error seg. 392 00:32:53,430 --> 00:32:55,830 Así que usando GDB no resuelve nuestro problema. 393 00:32:55,830 --> 00:32:59,120 Pero nos da una jerigonza, y resulta que esta jerigonza 394 00:32:59,120 --> 00:33:03,080 en realidad nos dice dónde está sucediendo. 395 00:33:03,080 --> 00:33:10,680 Para analizar esto un poco, este primer bit es la función en la que todo va mal. 396 00:33:10,680 --> 00:33:20,270 Hay un __ strcmp_sse4_2, y nos dice que está sucediendo en este archivo 397 00:33:20,270 --> 00:33:29,450 llamado sysdeps/i386, todo esto, de nuevo, una especie de desastre - pero la línea 254. 398 00:33:29,450 --> 00:33:31,670 Eso es un poco difícil de analizar. Normalmente, cuando ves cosas como esta, 399 00:33:31,670 --> 00:33:38,770 que significa que está seg con error en una de las bibliotecas del sistema. 400 00:33:38,770 --> 00:33:43,220 Así que algo que ver con strcmp. Ustedes han visto strcmp antes. 401 00:33:43,220 --> 00:33:52,730 No está loco, pero ¿significa esto que strcmp está roto o que hay un problema con strcmp? 402 00:33:52,730 --> 00:33:57,110 ¿Qué te parece, Alejandro? 403 00:33:57,110 --> 00:34:04,890 [Alexander] ¿Es que - es de 254 la línea? Y - no el binario, pero no es sus techos, 404 00:34:04,890 --> 00:34:10,590 y luego hay otro idioma para cada función. ¿Eso es 254 en esa función, o -? 405 00:34:10,590 --> 00:34:21,460 >> Es la línea 254. Parece que en este archivo. S, por lo que es probable que el código ensamblador. 406 00:34:21,460 --> 00:34:25,949 >> Sin embargo, creo que la cosa más urgente es, porque hemos conseguido un fallo seg, 407 00:34:25,949 --> 00:34:29,960 y parece como si viniera de la función strcmp, 408 00:34:29,960 --> 00:34:38,030 Qué implica esto, entonces, que strcmp se rompe? 409 00:34:38,030 --> 00:34:42,290 No debería, esperanzado. Así que sólo porque usted tiene un fallo de segmentación 410 00:34:42,290 --> 00:34:49,480 en una de las funciones del sistema, por lo general eso significa que no lo han llamado correctamente. 411 00:34:49,480 --> 00:34:52,440 La forma más rápida que se puede hacer para averiguar lo que realmente está pasando 412 00:34:52,440 --> 00:34:55,500 cuando ves algo loco como este, cada vez que vea una falla seg, 413 00:34:55,500 --> 00:34:59,800 especialmente si usted tiene un programa que está utilizando más que principal, 414 00:34:59,800 --> 00:35:03,570 es utilizar un backtrace. 415 00:35:03,570 --> 00:35:13,080 I abreviar backtrace por escrito bt, en oposición a la palabra traza completa. 416 00:35:13,080 --> 00:35:16,510 Pero Charlotte, lo que ocurre cuando se escribe bt y pulse Enter? 417 00:35:16,510 --> 00:35:23,200 [Charlotte] Me muestra dos líneas, la línea 0 y la línea 1. 418 00:35:23,200 --> 00:35:26,150 Sí >>. Así que la línea 0 y la línea 1. 419 00:35:26,150 --> 00:35:34,560 Estos son los marcos de pila reales que están actualmente en juego cuando el programa se estrelló. 420 00:35:34,560 --> 00:35:42,230 A partir del marco superior, el marco 0, e ir a la parte inferior más, que es el cuadro 1. 421 00:35:42,230 --> 00:35:45,140 Nuestro marco superior es el marco strcmp. 422 00:35:45,140 --> 00:35:50,080 Usted puede pensar en esto como similar al problema que estábamos haciendo en el concurso con los punteros, 423 00:35:50,080 --> 00:35:54,890 donde habíamos intercambiar marco de pila en la parte superior del marco de pila principal, 424 00:35:54,890 --> 00:35:59,700 y tuvimos las variables que se utilizan swaps en la parte superior de las variables que se utilizan principal. 425 00:35:59,700 --> 00:36:08,440 Aquí nuestro accidente ocurrió en nuestra función strcmp, que fue llamado por nuestra función principal, 426 00:36:08,440 --> 00:36:14,370 y backtrace nos está dando no sólo las funciones en que las cosas fallidas, 427 00:36:14,370 --> 00:36:16,440 pero también se nos dice que todo fue llamado. 428 00:36:16,440 --> 00:36:18,830 Así que si me desplazo en un poco más a la derecha, 429 00:36:18,830 --> 00:36:26,110 podemos ver que sí, que estábamos en la línea 254 de este archivo strcmp-sse4.s. 430 00:36:26,110 --> 00:36:32,540 Pero la llamada se hizo en buggy1.c, línea 6. 431 00:36:32,540 --> 00:36:35,960 Así que eso significa que podemos hacer - es simplemente podemos ir a ver hacia fuera y ver lo que estaba pasando 432 00:36:35,960 --> 00:36:39,930 en buggy1.c, línea 6. 433 00:36:39,930 --> 00:36:43,780 Una vez más, hay un par de maneras de hacer esto. Uno es para salir del GDB 434 00:36:43,780 --> 00:36:49,460 o tiene su código abierto en otra ventana y referencia cruzada. 435 00:36:49,460 --> 00:36:54,740 Eso, en sí mismo, es bastante útil porque ahora si usted está en horario de oficina 436 00:36:54,740 --> 00:36:57,220 y usted tiene una falla seg y su TF está preguntando donde todo se rompía, 437 00:36:57,220 --> 00:36:59,710 usted puede decir: "Oh, la línea 6. No sé lo que está pasando, 438 00:36:59,710 --> 00:37:03,670 pero algo en la línea 6 está causando mi programa de romper. " 439 00:37:03,670 --> 00:37:10,430 La otra manera de hacerlo es que usted puede utilizar este comando llamado de lista en GDB. 440 00:37:10,430 --> 00:37:13,650 También se puede abreviar con l. 441 00:37:13,650 --> 00:37:18,910 Así que si llegamos a l, ¿qué hacemos aquí? 442 00:37:18,910 --> 00:37:21,160 Tenemos un montón de cosas raras. 443 00:37:21,160 --> 00:37:26,030 Este es el código ensamblador real 444 00:37:26,030 --> 00:37:29,860 que es en strcmp_sse4_2. 445 00:37:29,860 --> 00:37:32,440 Esto parece un poco funky, 446 00:37:32,440 --> 00:37:36,520 y la razón por la que estamos recibiendo es porque en este momento, 447 00:37:36,520 --> 00:37:40,160 GDB nos tiene en el marco 0. 448 00:37:40,160 --> 00:37:43,070 >> Así que en cualquier momento nos fijamos en las variables, en cualquier momento nos fijamos en el código fuente, 449 00:37:43,070 --> 00:37:50,530 estamos viendo el código fuente que pertenece al marco de pila que se encuentra, 450 00:37:50,530 --> 00:37:53,200 Así que para conseguir algo significativo, tenemos que 451 00:37:53,200 --> 00:37:57,070 pasar a un marco de pila que tiene más sentido. 452 00:37:57,070 --> 00:38:00,180 En este caso, el marco de pila principal tendría sentido un poco más, 453 00:38:00,180 --> 00:38:02,680 porque ese era realmente el código que nosotros escribimos. 454 00:38:02,680 --> 00:38:05,330 No es el código strcmp. 455 00:38:05,330 --> 00:38:08,650 La forma en que se puede mover entre los cuadros, en este caso, porque tenemos dos, 456 00:38:08,650 --> 00:38:10,430 tenemos 0 y 1, 457 00:38:10,430 --> 00:38:13,650 lo hace con el arriba y abajo los comandos. 458 00:38:13,650 --> 00:38:18,480 Si me mudo a un fotograma, 459 00:38:18,480 --> 00:38:21,770 ahora estoy en el marco de la pila principal. 460 00:38:21,770 --> 00:38:24,330 Me puedo mover hacia abajo para volver a donde estaba, 461 00:38:24,330 --> 00:38:32,830 subir de nuevo, volver a bajar, y subir de nuevo. 462 00:38:32,830 --> 00:38:39,750 Si vuelves a hacer su programa en GDB, se obtiene un accidente, se obtiene la traza de depuración, 463 00:38:39,750 --> 00:38:42,380 y se ve que está en algún archivo que usted no sabe lo que está pasando. 464 00:38:42,380 --> 00:38:45,460 Intenta lista, el código no se ve familiar, 465 00:38:45,460 --> 00:38:48,150 echar un vistazo a sus cuadros y averiguar dónde se encuentra. 466 00:38:48,150 --> 00:38:51,010 Usted está probablemente en el marco de pila incorrecta. 467 00:38:51,010 --> 00:38:58,760 O por lo menos usted está en un marco de pila que no es la que realmente se puede depurar. 468 00:38:58,760 --> 00:39:03,110 Ahora que estamos en el marco de pila apropiado, estamos en el principal, 469 00:39:03,110 --> 00:39:08,100 Ahora podemos usar el comando list para averiguar lo que la línea era. 470 00:39:08,100 --> 00:39:13,590 Y usted puede ver, sino que lo imprimió para nosotros aquí. 471 00:39:13,590 --> 00:39:19,470 Pero podemos llegar a una lista de todo lo mismo, y la lista nos da esta impresión agradable 472 00:39:19,470 --> 00:39:23,920 del código fuente real que está pasando aquí. 473 00:39:23,920 --> 00:39:26,420 >> En particular, podemos mirar a la línea 6. 474 00:39:26,420 --> 00:39:29,330 Podemos ver lo que está pasando aquí. 475 00:39:29,330 --> 00:39:31,250 Y parece que estamos haciendo una comparación de cadenas 476 00:39:31,250 --> 00:39:41,050 entre la cadena "CS50" y rocas argv [1]. 477 00:39:41,050 --> 00:39:45,700 Algo de esto se caiga. 478 00:39:45,700 --> 00:39:54,120 Así Missy, ¿tiene usted alguna idea sobre lo que podría estar pasando aquí? 479 00:39:54,120 --> 00:39:59,400 [Missy] No sé por qué está fallando. >> No sé por qué está rompiendo? 480 00:39:59,400 --> 00:40:02,700 Jimmy, alguna idea? 481 00:40:02,700 --> 00:40:06,240 [Jimmy] No estoy del todo seguro, pero comparar la última vez que se utilizó cadena, 482 00:40:06,240 --> 00:40:10,260 o strcmp, teníamos como tres casos diferentes bajo el mismo. 483 00:40:10,260 --> 00:40:12,800 No teníamos un ==, no creo que, justo en esa primera línea. 484 00:40:12,800 --> 00:40:16,700 En su lugar, se dividió en tres, y uno era == 0, 485 00:40:16,700 --> 00:40:19,910 uno era <0, creo, y uno fue> 0. 486 00:40:19,910 --> 00:40:22,590 Así que tal vez algo así? Sí >>. Así que esta cuestión 487 00:40:22,590 --> 00:40:27,200 de que estamos haciendo la comparación correcta? 488 00:40:27,200 --> 00:40:31,660 Stella? ¿Alguna idea? 489 00:40:31,660 --> 00:40:38,110 [Stella] Yo no estoy seguro. >> No estoy seguro. Daniel? Pensamientos? Bien. 490 00:40:38,110 --> 00:40:44,770 Resulta que lo que está sucediendo aquí es cuando nos encontramos con el programa 491 00:40:44,770 --> 00:40:48,370 y nos dieron la culpa seg, al ejecutar el programa por primera vez, Daniel, 492 00:40:48,370 --> 00:40:50,800 se le dan los argumentos de línea de comandos? 493 00:40:50,800 --> 00:40:58,420 [Daniel] >> No. No. En ese caso, ¿cuál es el valor de argv [1]? 494 00:40:58,420 --> 00:41:00,920 >> No hay ningún valor. >> Derecho. 495 00:41:00,920 --> 00:41:06,120 Bueno, no hay ningún valor de cadena apropiado. 496 00:41:06,120 --> 00:41:10,780 Pero hay algo de valor. ¿Cuál es el valor que se almacena allí? 497 00:41:10,780 --> 00:41:15,130 >> Un valor basura? >> Es un valor basura o, en este caso, 498 00:41:15,130 --> 00:41:19,930 el final de la matriz argv siempre termina con null. 499 00:41:19,930 --> 00:41:26,050 Entonces, ¿qué he guardado allí es nulo. 500 00:41:26,050 --> 00:41:30,810 La otra manera de resolver esto, en lugar de pensar a través, 501 00:41:30,810 --> 00:41:33,420 es tratar de imprimir. 502 00:41:33,420 --> 00:41:35,880 Aquí es donde me estaba diciendo que el uso de GDB es grande, 503 00:41:35,880 --> 00:41:40,640 porque usted puede imprimir todas las variables, todos los valores que desea 504 00:41:40,640 --> 00:41:43,230 utilizar este comando práctico-excelente p. 505 00:41:43,230 --> 00:41:48,520 Así que si teclea p y luego escriba el valor de una variable o el nombre de una variable, 506 00:41:48,520 --> 00:41:55,320 decir, argc, veo que argc es 1. 507 00:41:55,320 --> 00:42:01,830 Si desea imprimir argv [0], puedo hacerlo sin más. 508 00:42:01,830 --> 00:42:04,840 Y como hemos visto, argv [0] es siempre el nombre de su programa, 509 00:42:04,840 --> 00:42:06,910 siempre el nombre del ejecutable. 510 00:42:06,910 --> 00:42:09,740 Aquí se ve que tiene el nombre de ruta completo. 511 00:42:09,740 --> 00:42:15,920 También puede imprimir argv [1] y ver qué pasa. 512 00:42:15,920 --> 00:42:20,890 >> Aquí tenemos a este tipo de valor místico. 513 00:42:20,890 --> 00:42:23,890 Conseguimos este 0x0. 514 00:42:23,890 --> 00:42:27,850 Recuerde que al comienzo de la legislatura, cuando hablamos de números hexadecimales? 515 00:42:27,850 --> 00:42:34,680 O que pocas dudas al final del conjunto de procesadores 0 sobre cómo representar 50 en hexadecimal? 516 00:42:34,680 --> 00:42:39,410 La forma de escribir los números hexadecimales de CS, no sólo a nosotros mismos confundir 517 00:42:39,410 --> 00:42:46,080 con números decimales, es que siempre les prefijo 0x. 518 00:42:46,080 --> 00:42:51,420 Así que este prefijo 0x siempre sólo significa interpretar el siguiente número como un número hexadecimal, 519 00:42:51,420 --> 00:42:57,400 no como una cadena, no como un número decimal, no como un número binario. 520 00:42:57,400 --> 00:43:02,820 Puesto que el número 5-0 es un número válido en hexadecimal. 521 00:43:02,820 --> 00:43:06,240 Y es un número en decimal, 50. 522 00:43:06,240 --> 00:43:10,050 Así que esto es sólo la forma en que eliminar la ambigüedad. 523 00:43:10,050 --> 00:43:14,860 Así 0x0 medio hexadecimal 0, lo cual también es decimal, binario 0 0. 524 00:43:14,860 --> 00:43:17,030 Es sólo el valor 0. 525 00:43:17,030 --> 00:43:22,630 Resulta que esto es lo nula es, en realidad, en la memoria. 526 00:43:22,630 --> 00:43:25,940 Null es 0. 527 00:43:25,940 --> 00:43:37,010 Aquí, el elemento almacenado en argv [1] es nulo. 528 00:43:37,010 --> 00:43:45,220 Así que estamos tratando de comparar nuestro "CS50 rocks" cadena en una cadena nula. 529 00:43:45,220 --> 00:43:48,130 Así desreferencia nula, intentando tener acceso a las cosas en null, 530 00:43:48,130 --> 00:43:55,050 los que normalmente se va a producir algún tipo de fallo de segmentación o de otras cosas malas sucedan. 531 00:43:55,050 --> 00:43:59,350 Y resulta que strcmp no comprueba para ver 532 00:43:59,350 --> 00:44:04,340 si usted ha pasado en un valor que es nulo. 533 00:44:04,340 --> 00:44:06,370 Por el contrario, sólo sigue adelante, trata de hacer lo suyo, 534 00:44:06,370 --> 00:44:14,640 y si seg faltas, seg faltas, y es tu problema. Tienes que ir a arreglarlo. 535 00:44:14,640 --> 00:44:19,730 Muy rápidamente, ¿cómo podemos solucionar este problema? Charlotte? 536 00:44:19,730 --> 00:44:23,540 [Charlotte] Puede comprobar si el uso. 537 00:44:23,540 --> 00:44:32,240 Así que si argv [1] es nulo, == 0, entonces devolver 1, o algo así [ininteligible]. 538 00:44:32,240 --> 00:44:34,590 Sí >>. Así que esa es una buena manera de hacerlo, como podemos comprobar, 539 00:44:34,590 --> 00:44:39,230 el valor que está a punto de pasar a strcmp, argv [1], se lo nulo? 540 00:44:39,230 --> 00:44:45,830 Si es nulo, entonces podemos decir que está bien, abortar. 541 00:44:45,830 --> 00:44:49,450 >> Una forma más común de hacer esto es utilizar el valor de argc. 542 00:44:49,450 --> 00:44:52,040 Se puede ver aquí en el comienzo de principal, 543 00:44:52,040 --> 00:44:58,040 omitimos que la primera prueba que solemos hacer cuando usamos argumentos de línea de comandos, 544 00:44:58,040 --> 00:45:05,240 que es para probar si nuestro valor de argc es lo que esperamos. 545 00:45:05,240 --> 00:45:10,290 En este caso, estamos esperando por lo menos dos argumentos, 546 00:45:10,290 --> 00:45:13,660 el nombre del programa más el otro. 547 00:45:13,660 --> 00:45:17,140 Debido a que estamos a punto de usar el segundo argumento aquí. 548 00:45:17,140 --> 00:45:21,350 Así que tener algún tipo de prueba de antemano, antes de nuestra llamada strcmp 549 00:45:21,350 --> 00:45:37,390 que las pruebas sean o no argv es al menos 2, también podría hacer el mismo tipo de cosas. 550 00:45:37,390 --> 00:45:40,620 Podemos ver si eso funciona, ejecute el programa de nuevo. 551 00:45:40,620 --> 00:45:45,610 Siempre se puede reiniciar el programa dentro de GDB, que es realmente bonita. 552 00:45:45,610 --> 00:45:49,310 Se puede correr, y cuando se pasa argumentos a su programa, 553 00:45:49,310 --> 00:45:53,060 los pases en cuando se llama a correr, no al arrancar GDB. 554 00:45:53,060 --> 00:45:57,120 De esa manera usted puede mantener invocando el programa con argumentos diferentes cada vez. 555 00:45:57,120 --> 00:46:08,080 Corred de tal manera o otra vez, puedo escribir r, y vamos a ver qué pasa si escribimos "hola". 556 00:46:08,080 --> 00:46:11,140 Siempre se te preguntará si quieres empezar desde el principio otra vez. 557 00:46:11,140 --> 00:46:17,490 Por lo general, lo quiero empezar desde el principio otra vez. 558 00:46:17,490 --> 00:46:25,010 Y en este punto, se reinicia de nuevo, imprime 559 00:46:25,010 --> 00:46:28,920 el programa que se está ejecutando, buggy1, con el argumento hola, 560 00:46:28,920 --> 00:46:32,720 e imprime esta salida estándar, sino que dice: "Usted recibe una D," cara triste. 561 00:46:32,720 --> 00:46:37,610 Pero no nos falla seg. Se dijo que el proceso terminó normalmente. 562 00:46:37,610 --> 00:46:39,900 Así que se ve muy bien. 563 00:46:39,900 --> 00:46:43,050 No más culpa seg, lo hemos hecho pasado, 564 00:46:43,050 --> 00:46:48,190 por lo que parece que era de hecho el error seg culpa que nos iban a dar. 565 00:46:48,190 --> 00:46:51,540 Por desgracia, nos dice que estamos llegando a una D. 566 00:46:51,540 --> 00:46:54,090 >> Podemos volver atrás y mirar el código y ver lo que estaba pasando allí 567 00:46:54,090 --> 00:46:57,980 para averiguar lo que era - por qué se nos está diciendo que tenemos una D. 568 00:46:57,980 --> 00:47:03,690 Vamos a ver, aquí se esta printf diciendo que tienes una D. 569 00:47:03,690 --> 00:47:08,540 Si tecleamos lista, que se mantenga la lista escribiendo, sigue iterando a través de su programa, 570 00:47:08,540 --> 00:47:10,940 por lo que voy a mostrar las primeras líneas de su programa. 571 00:47:10,940 --> 00:47:15,450 A continuación, le mostraremos las próximas líneas, y el trozo siguiente, y el siguiente trozo. 572 00:47:15,450 --> 00:47:18,240 Y va a seguir tratando de bajar. 573 00:47:18,240 --> 00:47:21,180 Y ahora vamos a llegar a "alinear el número 16 está fuera de alcance". 574 00:47:21,180 --> 00:47:23,940 Debido a que sólo cuenta con 15 líneas. 575 00:47:23,940 --> 00:47:30,310 Si se llega a este punto, y su pregunta: "¿Qué debo hacer?" puede utilizar el comando help. 576 00:47:30,310 --> 00:47:34,340 Utilice ayudar y luego darle el nombre de un comando. 577 00:47:34,340 --> 00:47:36,460 Y ves el BGF nos da todo este tipo de cosas. 578 00:47:36,460 --> 00:47:43,870 Dice: "Sin un argumento, una lista de diez líneas o más, después de todo el listado anterior. 579 00:47:43,870 --> 00:47:47,920 Lista - lista las diez líneas antes - " 580 00:47:47,920 --> 00:47:52,960 Así que vamos a tratar de usar menos de la lista. 581 00:47:52,960 --> 00:47:57,000 Y que las listas de las 10 líneas anteriores, se puede jugar con la lista un poco. 582 00:47:57,000 --> 00:48:02,330 Usted puede hacer la lista, lista -, incluso se puede dar una lista de un número, como lista 8, 583 00:48:02,330 --> 00:48:07,500 y que va a enumerar las 10 líneas en torno a la línea 8. 584 00:48:07,500 --> 00:48:10,290 Y usted puede ver lo que está pasando aquí es que tienes un simple if else. 585 00:48:10,290 --> 00:48:13,980 Si escribe en CS50 rocas, imprime "Se obtiene un sobresaliente" 586 00:48:13,980 --> 00:48:16,530 De lo contrario, se imprime "Se obtiene una D." 587 00:48:16,530 --> 00:48:23,770 Bummer ciudad. Está bien. ¿Sí? 588 00:48:23,770 --> 00:48:26,730 >> [Daniel] Así que cuando he intentado hacer CS50 rocas sin las comillas, 589 00:48:26,730 --> 00:48:29,290 dice "Te dan una D." 590 00:48:29,290 --> 00:48:32,560 Necesitaba las comillas para conseguir que funcione, ¿por qué es eso? 591 00:48:32,560 --> 00:48:38,490 Sí >>. Resulta que cuando - este es otro dato poco divertido - 592 00:48:38,490 --> 00:48:47,900 al ejecutar el programa, si lo ejecutamos y nos escribe en CS50 rocas, 593 00:48:47,900 --> 00:48:50,800 al igual que Daniel estaba diciendo que él hizo, y pulsar Intro, 594 00:48:50,800 --> 00:48:52,870 todavía dice que obtenemos una D. 595 00:48:52,870 --> 00:48:55,580 Y la pregunta es, ¿por qué es esto? 596 00:48:55,580 --> 00:49:02,120 Y resulta que tanto nuestro terminal y GDB analizar estos como dos argumentos distintos. 597 00:49:02,120 --> 00:49:04,800 Porque cuando hay un espacio, que está implicado como 598 00:49:04,800 --> 00:49:08,730 el primer argumento terminó, el siguiente argumento está a punto de comenzar. 599 00:49:08,730 --> 00:49:13,260 La forma de combinar los dos en, o perdón, en un argumento, 600 00:49:13,260 --> 00:49:18,510 es el uso de las comillas. 601 00:49:18,510 --> 00:49:29,560 Así que ahora, si lo ponemos entre comillas y ejecutarlo de nuevo, obtenemos una A. 602 00:49:29,560 --> 00:49:38,780 Así que para recapitular, sin comillas, CS50 y las rocas son interpretadas como dos argumentos distintos. 603 00:49:38,780 --> 00:49:45,320 Con las cotizaciones, se analiza como un argumento completo. 604 00:49:45,320 --> 00:49:53,070 >> Podemos ver esto con un punto de interrupción. 605 00:49:53,070 --> 00:49:54,920 Hasta ahora hemos estado funcionando nuestro programa, y ​​que se está ejecutando ha 606 00:49:54,920 --> 00:49:58,230 hasta que lo seg fallas o éxitos de un error 607 00:49:58,230 --> 00:50:05,930 o hasta que haya salido y todo ha sido totalmente bien. 608 00:50:05,930 --> 00:50:08,360 Esto no es necesariamente lo más útil, porque a veces 609 00:50:08,360 --> 00:50:11,840 tiene un error en su programa, pero no es la causa de un fallo de segmentación. 610 00:50:11,840 --> 00:50:16,950 No es la causa de su programa para detener o algo así. 611 00:50:16,950 --> 00:50:20,730 La manera de conseguir GDB para detener su programa en un punto particular 612 00:50:20,730 --> 00:50:23,260 es establecer un punto de interrupción. 613 00:50:23,260 --> 00:50:26,520 Usted puede hacer esto mediante el establecimiento de un punto de interrupción en un nombre de función 614 00:50:26,520 --> 00:50:30,770 o puede establecer un punto de interrupción en una línea de código en particular. 615 00:50:30,770 --> 00:50:34,450 Me gustaría establecer puntos de interrupción en los nombres de funciones, porque - fácil de recordar, 616 00:50:34,450 --> 00:50:37,700 y si usted realmente entrar y cambiar el código fuente un poco, 617 00:50:37,700 --> 00:50:42,020 entonces el punto de interrupción que se aloja en el mismo lugar dentro de su código. 618 00:50:42,020 --> 00:50:44,760 Mientras que si usted está utilizando los números de línea, y cambiar los números de línea 619 00:50:44,760 --> 00:50:51,740 porque agrega o elimina algo de código, a continuación, sus puntos de ruptura están totalmente jodido. 620 00:50:51,740 --> 00:50:58,590 Una de las cosas más comunes que hacen es establecer un punto de interrupción en la función principal. 621 00:50:58,590 --> 00:51:05,300 A menudo voy a arrancar GDB, voy a escribir b principal, pulse Enter, y que va a establecer un punto de interrupción 622 00:51:05,300 --> 00:51:10,630 la función principal, que simplemente dice, "Pausa el programa tan pronto como empiece a correr" 623 00:51:10,630 --> 00:51:17,960 y de esa manera, cuando ejecuto mi programa con, digamos, CS50 rocas como dos argumentos 624 00:51:17,960 --> 00:51:24,830 y pulse la tecla Enter, se vuelve a la función principal y se detiene justo en la primera línea, 625 00:51:24,830 --> 00:51:30,620 justo antes de que evalúa la función strcmp. 626 00:51:30,620 --> 00:51:34,940 >> Desde que estoy en pausa, ahora puedo empezar limpiando alrededor y ver lo que está pasando 627 00:51:34,940 --> 00:51:40,250 con todas las diferentes variables que se pasan en mi programa. 628 00:51:40,250 --> 00:51:43,670 Aquí puedo imprimir argc y ver lo que está pasando. 629 00:51:43,670 --> 00:51:50,030 Ver que argc es 3, porque tiene 3 valores diferentes en el mismo. 630 00:51:50,030 --> 00:51:54,060 Tiene el nombre del programa, tiene el primer argumento y el segundo argumento. 631 00:51:54,060 --> 00:52:09,330 Podemos imprimir los al mirar argv [0], argv [1], y argv [2]. 632 00:52:09,330 --> 00:52:12,030 Así que ahora también se puede ver por qué esta llamada strcmp va a fracasar, 633 00:52:12,030 --> 00:52:21,650 porque ves que se divide el CS50 y las rocas en dos argumentos distintos. 634 00:52:21,650 --> 00:52:27,250 En este punto, una vez que has llegado a un punto de interrupción, puede continuar con el paso a través de su programa 635 00:52:27,250 --> 00:52:32,920 línea por línea, en lugar de empezar su programa de nuevo. 636 00:52:32,920 --> 00:52:35,520 Así que si usted no quiere comenzar su programa de nuevo y seguimos desde aquí, 637 00:52:35,520 --> 00:52:41,970 puede utilizar el comando continue y continuará ejecutar el programa hasta el final. 638 00:52:41,970 --> 00:52:45,010 Al igual que lo hizo aquí. 639 00:52:45,010 --> 00:52:54,880 Sin embargo, si se me reinicia el programa, CS50 rocas, golpea mi punto de interrupción una vez más, 640 00:52:54,880 --> 00:52:59,670 y esta vez, si no quiere sólo tiene que ir todo el camino a través del resto del programa, 641 00:52:59,670 --> 00:53:08,040 Puedo usar el comando siguiente, que yo también abreviar con n. 642 00:53:08,040 --> 00:53:12,960 Y esto va a pasar por la línea de programa en línea. 643 00:53:12,960 --> 00:53:17,530 Así que usted puede ver las cosas como ejecutar, a medida que cambian las variables, como las cosas se actualiza. 644 00:53:17,530 --> 00:53:21,550 Lo cual es bastante agradable. 645 00:53:21,550 --> 00:53:26,570 Lo bueno es otro lugar de repetir el mismo comando una y otra y otra vez, 646 00:53:26,570 --> 00:53:30,670 si simplemente pulsa Intro - así que aquí ves que no has escrito en cualquier cosa - 647 00:53:30,670 --> 00:53:33,780 si tan sólo pulsar Intro, se repetirá el comando anterior, 648 00:53:33,780 --> 00:53:36,900 o el comando GDB anterior que acabo de poner pulg 649 00:53:36,900 --> 00:53:56,000 Puedo mantener oprimir la tecla Enter y va a seguir paso a paso a través de mi código línea por línea. 650 00:53:56,000 --> 00:53:59,310 Me gustaría animar a ustedes para ir a ver los programas con errores de otros también. 651 00:53:59,310 --> 00:54:01,330 No tenemos tiempo para pasar por todos ellos hoy en la sección. 652 00:54:01,330 --> 00:54:05,890 El código fuente está ahí, así que usted puede tipo de ver lo que está pasando 653 00:54:05,890 --> 00:54:07,730 detrás de las escenas si te quedas realmente atascado, 654 00:54:07,730 --> 00:54:11,940 pero al menos, sólo la práctica de arrancar GDB, 655 00:54:11,940 --> 00:54:13,940 la ejecución del programa hasta que se rompe en usted, 656 00:54:13,940 --> 00:54:18,260 obtener la traza de depuración, averiguar cuál es la función del accidente se encontraba, 657 00:54:18,260 --> 00:54:24,450 lo que estaba en línea, la impresión de algunos valores de las variables, 658 00:54:24,450 --> 00:54:30,140 sólo por lo que tener una idea de ello, porque lo que realmente le ayudará en el futuro. 659 00:54:30,140 --> 00:54:36,340 En este punto, vamos a dejar de GDB, lo que lo hace dejar de usar o simplemente q. 660 00:54:36,340 --> 00:54:40,460 Si el programa está en el medio de funcionamiento todavía, y no ha salido, 661 00:54:40,460 --> 00:54:43,510 siempre le preguntará: "¿Estás seguro de que realmente quiere dejar de fumar?" 662 00:54:43,510 --> 00:54:48,770 Sólo puede golpear si. 663 00:54:48,770 --> 00:54:55,250 >> Ahora vamos a ver el siguiente problema que tenemos, que es el programa de gato. 664 00:54:55,250 --> 00:54:59,880 Si usted mira el corto en la reorientación y tuberías, verás que Tommy utiliza este programa 665 00:54:59,880 --> 00:55:07,540 que básicamente imprime toda la salida de un archivo en la pantalla. 666 00:55:07,540 --> 00:55:12,660 Así que si me quedo gato, en realidad es un programa integrado en el aparato, 667 00:55:12,660 --> 00:55:16,860 y si tienes Mac puedes hacer esto en tu Mac también, si usted abre terminal. 668 00:55:16,860 --> 00:55:25,630 Y nosotros - gato, digamos, cp.c, y pulse Enter. 669 00:55:25,630 --> 00:55:29,640 Lo que esto hizo, si nos desplazamos un poco y ver donde nos encontramos con la línea, 670 00:55:29,640 --> 00:55:40,440 o donde ejecutó el comando cat, que literalmente acaba de imprimir el contenido de cp.c a nuestra pantalla. 671 00:55:40,440 --> 00:55:44,140 Podemos ejecutarlo de nuevo y se puede poner en varios archivos juntos. 672 00:55:44,140 --> 00:55:49,880 Así que usted puede hacer cp.c gato, y entonces también podemos concatenar el archivo Cat.C, 673 00:55:49,880 --> 00:55:53,250 que es el programa que vamos a escribir, 674 00:55:53,250 --> 00:55:58,140 y que va a imprimir dos archivos de espaldas a nuestra pantalla. 675 00:55:58,140 --> 00:56:05,490 Así que si nos desplazamos un poco, vemos que cuando nos encontramos con este cp.c gato, Cat.C, 676 00:56:05,490 --> 00:56:17,110 primero se imprime el archivo cp, y luego a continuación, se imprime el archivo Cat.C aquí abajo. 677 00:56:17,110 --> 00:56:19,650 Vamos a usar esto para obtener sólo los pies mojados. 678 00:56:19,650 --> 00:56:25,930 Juega un poco con la impresión simple a la terminal, ver cómo funciona. 679 00:56:25,930 --> 00:56:39,170 Si ustedes abren con gedit Cat.C, pulse Enter, 680 00:56:39,170 --> 00:56:43,760 usted puede ver el programa que estamos a punto de escribir. 681 00:56:43,760 --> 00:56:48,980 Hemos incluido esta placa de la caldera agradable, así que no tiene que gastar tiempo escribiendo todo lo que fuera. 682 00:56:48,980 --> 00:56:52,310 También comprobamos que el número de argumentos pasados ​​pulg 683 00:56:52,310 --> 00:56:56,910 Nos imprimir un mensaje de uso agradable. 684 00:56:56,910 --> 00:57:00,950 >> Este es el tipo de cosas que, de nuevo, al igual que hemos estado hablando, 685 00:57:00,950 --> 00:57:04,490 es casi como la memoria muscular. 686 00:57:04,490 --> 00:57:07,190 Sólo recuerde que seguir haciendo el mismo tipo de cosas 687 00:57:07,190 --> 00:57:11,310 y siempre imprimiendo algún tipo de mensaje útil 688 00:57:11,310 --> 00:57:17,670 por lo que la gente sabe cómo ejecutar su programa. 689 00:57:17,670 --> 00:57:21,630 Con gato, es bastante simple, sólo vamos a ir a través de todos los diferentes argumentos 690 00:57:21,630 --> 00:57:24,300 que se pasaron a nuestro programa, y ​​vamos a imprimir 691 00:57:24,300 --> 00:57:29,950 su contenido hacia fuera a la pantalla de una en una. 692 00:57:29,950 --> 00:57:35,670 Para imprimir archivos fuera de la pantalla, vamos a hacer algo muy similar 693 00:57:35,670 --> 00:57:38,120 a lo que hicimos al final de la prueba. 694 00:57:38,120 --> 00:57:45,350 Al final de la prueba, que contratan programa, tuvimos que abrir un archivo, 695 00:57:45,350 --> 00:57:48,490 y luego tuvimos que imprimir en ella. 696 00:57:48,490 --> 00:57:54,660 En este caso, vamos a abrir un archivo, y vamos a leer de ella en su lugar. 697 00:57:54,660 --> 00:58:00,630 A continuación, vamos a imprimir, en lugar de a un archivo, vamos a imprimir en la pantalla. 698 00:58:00,630 --> 00:58:05,830 Así que la impresión en la pantalla que todos hemos hecho antes con printf. 699 00:58:05,830 --> 00:58:08,290 Así que no es demasiado loco. 700 00:58:08,290 --> 00:58:12,190 Pero la lectura de un archivo es un poco extraño. 701 00:58:12,190 --> 00:58:17,300 Vamos a pasar por eso un poco a la vez. 702 00:58:17,300 --> 00:58:20,560 Si ustedes volver a ese último problema en el quiz, problema 33, 703 00:58:20,560 --> 00:58:27,280 la primera línea que vamos a hacer aquí, al abrir el archivo, es muy similar a lo que hicimos allí. 704 00:58:27,280 --> 00:58:36,370 Entonces, Stella, ¿qué significa esa mirada línea como, cuando abrimos un archivo? 705 00:58:36,370 --> 00:58:47,510 [Stella] Capital * Archivo, Archivo - >> Bueno. >> - Es igual a fopen. >> Yup. 706 00:58:47,510 --> 00:58:55,980 Que en este caso es? Está en el comentario. 707 00:58:55,980 --> 00:59:06,930 >> Está en el comentario? argv [i] y el r? 708 00:59:06,930 --> 00:59:11,300 >> Exactamente. Muy bien. Así que Stella es totalmente correcto. 709 00:59:11,300 --> 00:59:13,720 Esto es lo que la línea se parece. 710 00:59:13,720 --> 00:59:19,670 Vamos a obtener una variable de secuencia de archivo, guárdelo en un FILE *, por lo que todas las tapas, 711 00:59:19,670 --> 00:59:25,720 FILE, *, y el nombre de esta variable será el archivo. 712 00:59:25,720 --> 00:59:32,250 Lo podríamos llamar lo que nos gusta. Podríamos llamarlo first_file o file_i, cualquier cosa que quisiera. 713 00:59:32,250 --> 00:59:37,590 Y luego el nombre del archivo que se aprobó en la línea de comandos para este programa. 714 00:59:37,590 --> 00:59:44,450 Así que está almacenado en argv [i] y luego vamos a abrir el archivo en modo de lectura. 715 00:59:44,450 --> 00:59:48,100 Ahora que hemos abierto el archivo, ¿qué es lo que siempre tenemos que recordar que hacer 716 00:59:48,100 --> 00:59:52,230 cada vez que hemos abierto un archivo? Cerca de él. 717 00:59:52,230 --> 00:59:57,220 Así Missy, ¿cómo cerrar un archivo? 718 00:59:57,220 --> 01:00:01,020 [Missy] fclose (archivo) >> fclose (archivo). Exactamente. 719 01:00:01,020 --> 01:00:05,340 Grande. Bien. Si nos fijamos en esto para hacer un comentario aquí mismo, 720 01:00:05,340 --> 01:00:11,940 que dice, "Open argv [i] y muestra su contenido a la salida estándar." 721 01:00:11,940 --> 01:00:15,460 >> Fuera Standard es un nombre raro. Stdout es sólo nuestra manera de decir 722 01:00:15,460 --> 01:00:22,880 queremos imprimir en el terminal; queremos imprimir la secuencia de salida estándar. 723 01:00:22,880 --> 01:00:26,450 En realidad, puede deshacerse de este comentario aquí. 724 01:00:26,450 --> 01:00:36,480 Yo lo voy a copiar y pegar ya que es lo que hicimos. 725 01:00:36,480 --> 01:00:41,290 En este punto, ahora tenemos que leer el bit de archivo de a poco. 726 01:00:41,290 --> 01:00:46,300 Hemos hablado de un par de maneras de leer archivos. 727 01:00:46,300 --> 01:00:51,830 ¿Cuáles son sus favoritos hasta el momento? 728 01:00:51,830 --> 01:00:57,960 Qué maneras has visto ni te acuerdas, para leer los archivos? 729 01:00:57,960 --> 01:01:04,870 [Daniel] fread? >> Fread? Así fread es uno. Jimmy, ¿conoces alguna otra? 730 01:01:04,870 --> 01:01:12,150 [Jimmy] >> No. Está bien. Nope. Charlotte? Alexander? ¿Algún otro? Bien. 731 01:01:12,150 --> 01:01:20,740 Así que los otros son fgetc, es el que vamos a usar. 732 01:01:20,740 --> 01:01:26,410 También hay fscanf; ustedes ver un patrón aquí? 733 01:01:26,410 --> 01:01:29,170 Todos comienzan con f. Nada que ver con un archivo. 734 01:01:29,170 --> 01:01:35,260 Hay fread, fgetc, fscanf. Estas son todas las funciones de lectura. 735 01:01:35,260 --> 01:01:49,120 Para escribir tenemos fwrite, tenemos fputc en lugar de fgetc. 736 01:01:49,120 --> 01:01:58,250 También hemos fprintf como vimos en el cuestionario. 737 01:01:58,250 --> 01:02:01,680 Dado que este es un problema que involucra la lectura de un archivo, 738 01:02:01,680 --> 01:02:04,940 vamos a utilizar una de estas tres funciones. 739 01:02:04,940 --> 01:02:10,890 No vamos a utilizar estas funciones aquí abajo. 740 01:02:10,890 --> 01:02:14,880 Estas funciones se encuentran todos en el estándar de E / S de la biblioteca. 741 01:02:14,880 --> 01:02:17,510 Así que si nos fijamos en la parte superior de este programa, 742 01:02:17,510 --> 01:02:24,110 se puede ver que ya hemos incluido el archivo de cabecera para el estándar de E / S de la biblioteca. 743 01:02:24,110 --> 01:02:27,120 Si queremos averiguar cuál queremos utilizar, 744 01:02:27,120 --> 01:02:29,690 siempre podemos abrir las páginas de manual. 745 01:02:29,690 --> 01:02:34,350 Así que podemos escribir stdio hombre 746 01:02:34,350 --> 01:02:43,180 y leer todo acerca de la entrada de stdio y funciones de salida en C. 747 01:02:43,180 --> 01:02:49,870 Y ya podemos ver oh, mira. Se menciona fgetc, se menciona fputc. 748 01:02:49,870 --> 01:02:57,220 Así que usted puede profundizar un poco más y ver, por ejemplo, fgetc 749 01:02:57,220 --> 01:03:00,060 y buscar en su página de manual. 750 01:03:00,060 --> 01:03:03,430 Usted puede ver que va junto con un montón de otras funciones: 751 01:03:03,430 --> 01:03:12,640 fgetc, fgets, getc, getchar, consigue, ungetc, y su entrada de caracteres y cadenas. 752 01:03:12,640 --> 01:03:19,180 Así que así es como se lee en caracteres y cadenas de los archivos de entrada estándar, 753 01:03:19,180 --> 01:03:21,990 que es esencialmente parte del usuario. 754 01:03:21,990 --> 01:03:24,780 Y así es como lo hacemos en real C. 755 01:03:24,780 --> 01:03:30,850 Así que esto no está utilizando el GetString y funciones getchar 756 01:03:30,850 --> 01:03:36,840 que se utilizó la biblioteca de CS50. 757 01:03:36,840 --> 01:03:39,710 Vamos a hacer este problema en un par de maneras 758 01:03:39,710 --> 01:03:43,430 de modo que usted puede ver dos maneras diferentes de hacerlo. 759 01:03:43,430 --> 01:03:48,490 Tanto la función fread que Daniel menciona y fgetc son buenas maneras de hacerlo. 760 01:03:48,490 --> 01:03:53,790 Creo fgetc es un poco más fácil, ya que sólo tiene, como usted ve, 761 01:03:53,790 --> 01:03:59,660 un argumento, el FILE * que estamos tratando de leer el carácter de, 762 01:03:59,660 --> 01:04:02,740 y su valor de retorno es un int. 763 01:04:02,740 --> 01:04:05,610 Y esto es un poco confuso, ¿no? 764 01:04:05,610 --> 01:04:11,450 >> Debido a que estamos llegando a un personaje, así que ¿por qué no hace una declaración char? 765 01:04:11,450 --> 01:04:18,700 Ustedes tienen alguna idea de por qué esto no puede devolver un char? 766 01:04:18,700 --> 01:04:25,510 [Missy respuestas, ininteligible] >> Yeah. Así que Missy es totalmente correcto. 767 01:04:25,510 --> 01:04:31,570 Si es ASCII, entonces este entero podría ser asignada a una charla real. 768 01:04:31,570 --> 01:04:33,520 Podría ser un carácter ASCII, y así es. 769 01:04:33,520 --> 01:04:36,220 Eso es exactamente lo que está pasando. 770 01:04:36,220 --> 01:04:39,190 Estamos usando un int simplemente porque tiene más bits. 771 01:04:39,190 --> 01:04:44,750 Es más grande que un char, nuestra charla sólo tiene 8 bits, 1 byte que en nuestras máquinas de 32 bits. 772 01:04:44,750 --> 01:04:48,520 Y un int tiene valor en los 4 bytes 'del espacio. 773 01:04:48,520 --> 01:04:50,940 Y resulta que la forma fgetc funciona, 774 01:04:50,940 --> 01:04:53,940 si se desplaza hacia abajo en nuestra sinopsis de esta página de manual un poco, 775 01:04:53,940 --> 01:05:05,000 desplácese hasta el fondo. Resulta que utilizan este valor especial llamado EOF. 776 01:05:05,000 --> 01:05:09,640 Es una constante especial como el valor devuelto por la función fgetc 777 01:05:09,640 --> 01:05:14,570 cada vez que se pulsa el final del archivo o si se produce un error. 778 01:05:14,570 --> 01:05:18,170 Y resulta que para hacer estas comparaciones con EOF correctamente, 779 01:05:18,170 --> 01:05:24,060 Quieres tener esa cantidad extra de información que usted tiene en un int 780 01:05:24,060 --> 01:05:28,420 en lugar de utilizar una variable char. 781 01:05:28,420 --> 01:05:32,130 A pesar de que está efectivamente fgetc conseguir un personaje de un archivo, 782 01:05:32,130 --> 01:05:38,450 quiere recordar que se está volviendo algo que es de tipo int a usted. 783 01:05:38,450 --> 01:05:41,360 Dicho esto, es bastante fácil de usar. 784 01:05:41,360 --> 01:05:44,960 Esto nos va a dar un carácter, por lo que todos tenemos que hacer es seguir pidiendo el archivo, 785 01:05:44,960 --> 01:05:48,440 "Dame el siguiente carácter, me da el siguiente carácter, dame el personaje que viene" 786 01:05:48,440 --> 01:05:51,400 hasta que lleguemos al final del archivo. 787 01:05:51,400 --> 01:05:54,730 Y eso va a tirar de un carácter a la vez de nuestro archivo, 788 01:05:54,730 --> 01:05:56,250 y entonces podemos hacer lo que queramos con ella. 789 01:05:56,250 --> 01:06:00,160 Podemos almacenar, podemos añadir a una cadena, podemos imprimir. 790 01:06:00,160 --> 01:06:04,630 Hacer nada de eso. 791 01:06:04,630 --> 01:06:09,600 >> Acercamiento a salir y volver a nuestro programa Cat.C, 792 01:06:09,600 --> 01:06:16,170 si vamos a utilizar fgetc, 793 01:06:16,170 --> 01:06:21,710 ¿cómo nos acercamos a esta siguiente línea de código? 794 01:06:21,710 --> 01:06:26,020 Vamos a usar - fread va a hacer algo un poco diferente. 795 01:06:26,020 --> 01:06:32,600 Y esta vez, sólo vamos a utilizar fgetc para obtener un carácter a la vez. 796 01:06:32,600 --> 01:06:40,910 Para procesar un archivo completo, lo que tenemos que hacer? 797 01:06:40,910 --> 01:06:44,030 ¿Cuántos personajes hay en un archivo? 798 01:06:44,030 --> 01:06:47,390 Hay un montón. Así que es probable que desee obtener una 799 01:06:47,390 --> 01:06:49,860 y luego otro y conseguir otro y conseguir otro. 800 01:06:49,860 --> 01:06:53,330 ¿Qué tipo de algoritmo crees que podría tener que usar aquí? 801 01:06:53,330 --> 01:06:55,470 ¿Qué tipo de -? [Alejandro] Un bucle for? >> Exactamente. 802 01:06:55,470 --> 01:06:57,500 Algún tipo de bucle. 803 01:06:57,500 --> 01:07:03,380 Un bucle es realmente grande, en este caso. 804 01:07:03,380 --> 01:07:08,620 Y, como usted decía, parece que quieres un lazo sobre la totalidad del expediente, 805 01:07:08,620 --> 01:07:11,820 conseguir un carácter a la vez. 806 01:07:11,820 --> 01:07:13,850 ¿Alguna sugerencia sobre lo que puede tener un aspecto parecido? 807 01:07:13,850 --> 01:07:22,090 [Alexander, ininteligible] 808 01:07:22,090 --> 01:07:30,050 >> Bueno, me lo dices en Inglés lo que estás tratando de hacer? [Alexander, ininteligible] 809 01:07:30,050 --> 01:07:36,270 Así que en este caso, parece que sólo estamos tratando de iterar sobre el archivo completo. 810 01:07:36,270 --> 01:07:45,330 [Alejandro] Así que > El tamaño de -? 811 01:07:45,330 --> 01:07:49,290 Supongo que el tamaño del archivo, ¿no? El tamaño - nos volveremos simplemente escribirlo así. 812 01:07:49,290 --> 01:07:57,470 Tamaño de archivo por el momento, i + +. 813 01:07:57,470 --> 01:08:04,610 Así que resulta que la forma de hacer esto utilizando fgetc, y esto es nuevo, 814 01:08:04,610 --> 01:08:10,460 es que no hay manera fácil de conseguir apenas el tamaño de un archivo 815 01:08:10,460 --> 01:08:16,979 con este "sizeof" tipo de construcción que haya visto antes. 816 01:08:16,979 --> 01:08:20,910 Cuando usamos esa función fgetc, estamos introduciendo algún tipo de 817 01:08:20,910 --> 01:08:29,069 nueva sintaxis, funky a este bucle, donde en lugar de utilizar simplemente un contador básico 818 01:08:29,069 --> 01:08:33,920 ir carácter por carácter, vamos a tirar un carácter a la vez, 819 01:08:33,920 --> 01:08:37,120 un carácter a la vez, y la manera en que sabemos que estamos en el final 820 01:08:37,120 --> 01:08:41,290 no es cuando hemos contado un número determinado de caracteres, 821 01:08:41,290 --> 01:08:49,939 pero cuando el personaje que sacar es que la final de carácter especial de archivo. 822 01:08:49,939 --> 01:08:58,689 Así que podemos hacer esto - Yo llamo a esta cap, y nosotros vamos a inicializar 823 01:08:58,689 --> 01:09:08,050 con nuestra primera llamada para obtener el primer carácter del archivo. 824 01:09:08,050 --> 01:09:14,979 Así que esta parte, justo aquí, esto se va a poner a un personaje fuera del archivo 825 01:09:14,979 --> 01:09:20,840 y almacenarlo en la variable ch. 826 01:09:20,840 --> 01:09:25,420 Vamos a seguir haciendo esto hasta que llegue al final del archivo, 827 01:09:25,420 --> 01:09:41,170 que hacemos por las pruebas de que el personaje no es igual a ese carácter EOF especial. 828 01:09:41,170 --> 01:09:48,750 Y a continuación, en lugar de hacer ch + +, que acaba de incrementar el valor, 829 01:09:48,750 --> 01:09:52,710 por lo que si leemos un fuera de un archivo, una A mayúscula, por ejemplo, 830 01:09:52,710 --> 01:09:56,810 ch + + nos daría b, y luego nos íbamos a c y d. 831 01:09:56,810 --> 01:09:59,310 Eso no es claramente lo que queremos. Lo que queremos aquí 832 01:09:59,310 --> 01:10:05,830 en esta última parte es que queremos obtener el siguiente carácter del archivo. 833 01:10:05,830 --> 01:10:09,500 >> Entonces, ¿cómo podemos obtener el siguiente carácter del archivo? 834 01:10:09,500 --> 01:10:13,470 ¿Cómo conseguimos el primer carácter del archivo? 835 01:10:13,470 --> 01:10:17,200 [Estudiante] fgetfile? >> Fgetc, o, lo siento, tenías toda la razón. 836 01:10:17,200 --> 01:10:20,470 Lo mal escrito ahí. Así que sí. 837 01:10:20,470 --> 01:10:26,240 Aquí en vez de hacer ch + +, 838 01:10:26,240 --> 01:10:29,560 sólo vamos a llamar fgetc (archivo) de nuevo 839 01:10:29,560 --> 01:10:39,180 y almacenar el resultado en la variable ch mismo. 840 01:10:39,180 --> 01:10:43,730 [Pregunta Estudiante, ininteligible] 841 01:10:43,730 --> 01:10:52,390 >> Aquí es donde estos tipos de archivo * son especiales. 842 01:10:52,390 --> 01:10:59,070 La forma de trabajar que es - cuando abra por primera vez - la primera vez que haga esa llamada fopen, 843 01:10:59,070 --> 01:11:04,260 El archivo * sirve efectivamente como un puntero al comienzo del archivo. 844 01:11:04,260 --> 01:11:12,830 Y cada vez que llame fgetc, se mueve un personaje a través del archivo. 845 01:11:12,830 --> 01:11:23,280 Así que cada vez que se llame a esto, usted está incrementando el apuntador de archivo por un carácter. 846 01:11:23,280 --> 01:11:26,210 Y cuando fgetc de nuevo, estás en movimiento a otro personaje 847 01:11:26,210 --> 01:11:28,910 y otro personaje y otro personaje y otro personaje. 848 01:11:28,910 --> 01:11:32,030 [Pregunta Estudiante, ininteligible] >> Y eso es - sí. 849 01:11:32,030 --> 01:11:34,810 Es un poco de esta magia bajo el capó. 850 01:11:34,810 --> 01:11:37,930 Usted acaba de seguir incrementando a través. 851 01:11:37,930 --> 01:11:46,510 En este punto, usted es capaz de trabajar realmente con un personaje. 852 01:11:46,510 --> 01:11:52,150 Entonces, ¿cómo podemos imprimir esto a la pantalla, ahora? 853 01:11:52,150 --> 01:11:58,340 Podemos utilizar la misma cosa printf que utilizamos antes. 854 01:11:58,340 --> 01:12:00,330 Que hemos estado usando durante todo el semestre. 855 01:12:00,330 --> 01:12:05,450 Podemos llamar a printf, 856 01:12:05,450 --> 01:12:21,300 y que puede pasar en el carácter justo de esa manera. 857 01:12:21,300 --> 01:12:27,430 Otra forma de hacerlo es en vez de usar printf y tener que hacer esta cadena de formato, 858 01:12:27,430 --> 01:12:29,490 También se puede utilizar una de las otras funciones. 859 01:12:29,490 --> 01:12:40,090 Podemos utilizar fputc, que imprime un carácter en la pantalla, 860 01:12:40,090 --> 01:12:52,580 excepto si nos fijamos en fputc - quiero alejar un poco. 861 01:12:52,580 --> 01:12:56,430 Vemos lo bueno es que se necesita en el carácter que leemos a cabo utilizando fgetc, 862 01:12:56,430 --> 01:13:05,100 pero entonces tenemos que darle un arroyo para imprimir. 863 01:13:05,100 --> 01:13:11,850 También puede utilizar la función putchar, que pondrá directamente a la salida estándar. 864 01:13:11,850 --> 01:13:16,070 Así que hay un montón de opciones diferentes que podemos usar para la impresión. 865 01:13:16,070 --> 01:13:19,580 Están todos en el estándar de E / S de la biblioteca. 866 01:13:19,580 --> 01:13:25,150 Cada vez que quiere imprimir - por lo printf, por defecto, se imprimirá en la norma especial fuera corriente, 867 01:13:25,150 --> 01:13:27,910 que es la salida estándar. 868 01:13:27,910 --> 01:13:41,300 Así que sólo puede referirse a él como una especie de magia este valor, stdout aquí. 869 01:13:41,300 --> 01:13:48,410 Oops. Poner el punto y coma afuera. 870 01:13:48,410 --> 01:13:52,790 >> Se trata de una gran cantidad de nueva información, funky aquí. 871 01:13:52,790 --> 01:13:58,600 Mucho de esto es muy idiomático, en el sentido de que este es el código 872 01:13:58,600 --> 01:14:05,700 lo que está escrito aquí sólo porque está limpio de leer, fácil de leer. 873 01:14:05,700 --> 01:14:11,520 Hay muchas maneras diferentes de hacerlo, muchas funciones diferentes que puede utilizar, 874 01:14:11,520 --> 01:14:14,680 pero tendemos a seguir sólo los mismos patrones una y otra vez. 875 01:14:14,680 --> 01:14:20,180 Así que no se sorprenda si usted ve un código como el que viene una y otra vez. 876 01:14:20,180 --> 01:14:25,690 Está bien. En este punto, tenemos que romper el día. 877 01:14:25,690 --> 01:14:31,300 Gracias por venir. Gracias por ver si estás en línea. Y nos vemos la próxima semana. 878 01:14:31,300 --> 01:14:33,890 [CS50.TV]