|
@@ -139,6 +139,284 @@ En esta experiencia de laboratorio te proveemos una clase `GPOI` con los siguie
|
139
|
139
|
---
|
140
|
140
|
|
141
|
141
|
|
|
142
|
+## Leyendo datos de un archivo de texto en C++
|
|
143
|
+
|
|
144
|
+En este laboratorio crearás un programa que lee datos de un archivo de texto. Puedes saltar esta sección si te sientes cómodo con tus destrezas de manejo de archivos de texto en C++.
|
|
145
|
+
|
|
146
|
+C++ provee funciones para leer y escribir datos en archivos. En este laboratorio usarás uno de los métodos más básicos de lectura: lectura secuencial de archivos de texto. Los **archivos de texto** consisten de caracteres ASCII que representan datos en alguno de los tipos primitivos de C++. Por ejemplo, supón que el archivo `nameAge.txt` contiene algunos datos sobre nombres y edades.
|
|
147
|
+
|
|
148
|
+```
|
|
149
|
+Tomas 34
|
|
150
|
+Marta 55
|
|
151
|
+Remigio 88
|
|
152
|
+Andrea 43
|
|
153
|
+```
|
|
154
|
+
|
|
155
|
+Para **leer** un archivo de texto como parte de un programa en C++, debemos conocer cómo están organizados los datos en el archivo y qué tipo de datos deseamos leer. El archivo `nameAge.txt` contiene cuatro líneas y cada línea contiene un string y un entero. A continuación un programa para leer el archivo de principio a fin mientras se imprimen los datos que se van leyendo en cada línea. Lee los comentarios del programa para entiendas sus partes:
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+```
|
|
159
|
+
|
|
160
|
+#include <iostream>
|
|
161
|
+
|
|
162
|
+// fstream es el header file que contiene clases, fu
|
|
163
|
+## Leyendo datos de un archivo de texto en C++
|
|
164
|
+
|
|
165
|
+En este laboratorio crearás un programa que lee datos de un archivo de texto. Puedes saltar esta sección si te sientes cómodo con tus destrezas de manejo de archivos de texto en C++.
|
|
166
|
+
|
|
167
|
+C++ provee funciones para leer y escribir datos en archivos. En este laboratorio usarás uno de los métodos más básicos de lectura: lectura secuencial de archivos de texto. Los **archivos de texto** consisten de caracteres ASCII que representan datos en alguno de los tipos primitivos de C++. Por ejemplo, supón que el archivo `nameAge.txt` contiene algunos datos sobre nombres y edades.
|
|
168
|
+
|
|
169
|
+```
|
|
170
|
+Tomas 34
|
|
171
|
+Marta 55
|
|
172
|
+Remigio 88
|
|
173
|
+Andrea 43
|
|
174
|
+```
|
|
175
|
+
|
|
176
|
+Para **leer** un archivo de texto como parte de un programa en C++, debemos conocer cómo están organizados los datos en el archivo y qué tipo de datos deseamos leer. El archivo `nameAge.txt` contiene cuatro líneas y cada línea contiene un string y un entero. A continuación un programa para leer el archivo de principio a fin mientras se imprimen los datos que se van leyendo en cada línea. Lee los comentarios del programa para entiendas sus partes:
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+```
|
|
180
|
+
|
|
181
|
+#include <iostream>
|
|
182
|
+
|
|
183
|
+// fstream es el header file que contiene clases, funciones y objetos
|
|
184
|
+// para trabjar con lectura y escritura de archivos.
|
|
185
|
+#include <fstream>
|
|
186
|
+
|
|
187
|
+using namespace std;
|
|
188
|
+
|
|
189
|
+int main(){
|
|
190
|
+
|
|
191
|
+ // Usaremos las siguientes dos variables para asignarle los
|
|
192
|
+ // valores que leemos en cada linea del archivo.
|
|
193
|
+ string name;
|
|
194
|
+ int age;
|
|
195
|
+
|
|
196
|
+ // Definimos el objeto que representará al archivo
|
|
197
|
+ ifstream inFile;
|
|
198
|
+
|
|
199
|
+ // Invocamos a la funcion open para que abra el file `nameAge.txt`
|
|
200
|
+ inFile.open("nameAge.txt");
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+ // Verificamos que el archivo ha sido debidamente abierto
|
|
204
|
+ if (!inFile.is_open()) {
|
|
205
|
+ cout << "Error openning file nameAge.txt\n";
|
|
206
|
+ exit(1);
|
|
207
|
+ }
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+ // Mientras haya datos por leer en el archivo, leer un string
|
|
211
|
+ // y un entero. Observa como usamos simbolo `>>`, parecido
|
|
212
|
+ // a como lo usamos con cin.
|
|
213
|
+
|
|
214
|
+ while (inFile >> name >> age) {
|
|
215
|
+ cout << name << " : " << age << endl;
|
|
216
|
+ }
|
|
217
|
+
|
|
218
|
+ // Cerrar el archivo.
|
|
219
|
+ inFile.close();
|
|
220
|
+
|
|
221
|
+ return 0;
|
|
222
|
+}
|
|
223
|
+```
|
|
224
|
+
|
|
225
|
+El objeto `ifstream` permite que leamos el archivo de forma **secuencial**. Lleva cuenta de la próxima posición a leer dentro del archivo. Cada vez que leemos uno o más datos (usando `inFile >> ____`) el objeto adelanta su posición para que el próximo `inFile >> ___` pueda leer los datos siguientes.
|
|
226
|
+
|
|
227
|
+Observa la linea `inFile >> name >> age`. Esa instrucción realiza varias tareas:
|
|
228
|
+
|
|
229
|
+* Lee un string y un int del archivo (si queda algo por leer) y se los asigna a las variables `name` y `age`.
|
|
230
|
+* Si pudo leer ambos datos, la expresión `inFile >> name >> age` evalúa `true`.
|
|
231
|
+* De lo contrario, la expresión evalúa `false`, saliendo del bloque while.
|
|
232
|
+
|
|
233
|
+A continuación algunos pedazos de código C++ para tareas comunes de lectura de archivos. Observa que en todas ellas:
|
|
234
|
+
|
|
235
|
+1. Creamos un objecto de clase `ifstream`, llamamos a su función `open` y verificamos que el archivo abrió correctamente.
|
|
236
|
+2. Creamos una o más variables para asignarles los valores que leeremos del archivo.
|
|
237
|
+3. Implementamos un ciclo que se repite mientras hayan datos que leer del archivo.
|
|
238
|
+4. Cerramos el archivo.
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+**Ejemplo 1**: Leer un archivo que solo contiene datos enteros y acumular sus valores.
|
|
243
|
+
|
|
244
|
+```
|
|
245
|
+ ifstream inFile;
|
|
246
|
+ int n;
|
|
247
|
+ int accum = 0;
|
|
248
|
+
|
|
249
|
+ inFile.open("nums.txt");
|
|
250
|
+
|
|
251
|
+ if (!inFile.is_open()) {
|
|
252
|
+ cout << "Error openning file nums.txt\n";
|
|
253
|
+ exit(1);
|
|
254
|
+ }
|
|
255
|
+
|
|
256
|
+ while (inFile >> n) {
|
|
257
|
+ accum = accum + n;
|
|
258
|
+ }
|
|
259
|
+
|
|
260
|
+ cout << "Total: " << accum << endl;
|
|
261
|
+
|
|
262
|
+ inFile.close();
|
|
263
|
+```
|
|
264
|
+
|
|
265
|
+**Ejemplo 2**: Contar el número de líneas en un archivo que contiene un nombre por línea. Luego imprimir el contenido de la línea del medio.
|
|
266
|
+
|
|
267
|
+```
|
|
268
|
+ ifstream inFile;
|
|
269
|
+ string name;
|
|
270
|
+ int ctr = 0;
|
|
271
|
+
|
|
272
|
+ inFile.open("names.txt");
|
|
273
|
+
|
|
274
|
+ if (!inFile.is_open()) {
|
|
275
|
+ cout << "Error openning file names.txt\n";
|
|
276
|
+ exit(1);
|
|
277
|
+ }
|
|
278
|
+
|
|
279
|
+ while (inFile >> name) {
|
|
280
|
+ ctr++;
|
|
281
|
+ }
|
|
282
|
+
|
|
283
|
+ cout << "Total number of lines: " << ctr << endl;
|
|
284
|
+
|
|
285
|
+ // Estos dos comandos retroceden el file al principio.
|
|
286
|
+ inFile.clear();
|
|
287
|
+ inFile.seekg(0);
|
|
288
|
+
|
|
289
|
+ for (int i = 0; i <= ctr / 2; i++) {
|
|
290
|
+ inFile >> name;
|
|
291
|
+ }
|
|
292
|
+
|
|
293
|
+ cout << "The name at the position " << ctr / 2 << ": " << name << endl;
|
|
294
|
+
|
|
295
|
+ inFile.close();
|
|
296
|
+```
|
|
297
|
+
|
|
298
|
+---
|
|
299
|
+
|
|
300
|
+---nciones y objetos
|
|
301
|
+// para trabjar con lectura y escritura de archivos.
|
|
302
|
+#include <fstream>
|
|
303
|
+
|
|
304
|
+using namespace std;
|
|
305
|
+
|
|
306
|
+int main(){
|
|
307
|
+
|
|
308
|
+ // Usaremos las siguientes dos variables para asignarle los
|
|
309
|
+ // valores que leemos en cada linea del archivo.
|
|
310
|
+ string name;
|
|
311
|
+ int age;
|
|
312
|
+
|
|
313
|
+ // Definimos el objeto que representará al archivo
|
|
314
|
+ ifstream inFile;
|
|
315
|
+
|
|
316
|
+ // Invocamos a la funcion open para que abra el file `nameAge.txt`
|
|
317
|
+ inFile.open("nameAge.txt");
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+ // Verificamos que el archivo ha sido debidamente abierto
|
|
321
|
+ if (!inFile.is_open()) {
|
|
322
|
+ cout << "Error openning file nameAge.txt\n";
|
|
323
|
+ exit(1);
|
|
324
|
+ }
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+ // Mientras haya datos por leer en el archivo, leer un string
|
|
328
|
+ // y un entero. Observa como usamos simbolo `>>`, parecido
|
|
329
|
+ // a como lo usamos con cin.
|
|
330
|
+
|
|
331
|
+ while (inFile >> name >> age) {
|
|
332
|
+ cout << name << " : " << age << endl;
|
|
333
|
+ }
|
|
334
|
+
|
|
335
|
+ // Cerrar el archivo.
|
|
336
|
+ inFile.close();
|
|
337
|
+
|
|
338
|
+ return 0;
|
|
339
|
+}
|
|
340
|
+```
|
|
341
|
+
|
|
342
|
+El objeto `ifstream` permite que leamos el archivo de forma **secuencial**. Lleva cuenta de la próxima posición a leer dentro del archivo. Cada vez que leemos uno o más datos (usando `inFile >> ____`) el objeto adelanta su posición para que el próximo `inFile >> ___` pueda leer los datos siguientes.
|
|
343
|
+
|
|
344
|
+Observa la linea `inFile >> name >> age`. Esa instrucción realiza varias tareas:
|
|
345
|
+
|
|
346
|
+* Lee un string y un int del archivo (si queda algo por leer) y se los asigna a las variables `name` y `age`.
|
|
347
|
+* Si pudo leer ambos datos, la expresión `inFile >> name >> age` evalúa `true`.
|
|
348
|
+* De lo contrario, la expresión evalúa `false`, saliendo del bloque while.
|
|
349
|
+
|
|
350
|
+A continuación algunos pedazos de código C++ para tareas comunes de lectura de archivos. Observa que en todas ellas:
|
|
351
|
+
|
|
352
|
+1. Creamos un objecto de clase `ifstream`, llamamos a su función `open` y verificamos que el archivo abrió correctamente.
|
|
353
|
+2. Creamos una o más variables para asignarles los valores que leeremos del archivo.
|
|
354
|
+3. Implementamos un ciclo que se repite mientras hayan datos que leer del archivo.
|
|
355
|
+4. Cerramos el archivo.
|
|
356
|
+
|
|
357
|
+
|
|
358
|
+
|
|
359
|
+**Ejemplo 1**: Leer un archivo que solo contiene datos enteros y acumular sus valores.
|
|
360
|
+
|
|
361
|
+```
|
|
362
|
+ ifstream inFile;
|
|
363
|
+ int n;
|
|
364
|
+ int accum = 0;
|
|
365
|
+
|
|
366
|
+ inFile.open("nums.txt");
|
|
367
|
+
|
|
368
|
+ if (!inFile.is_open()) {
|
|
369
|
+ cout << "Error openning file nums.txt\n";
|
|
370
|
+ exit(1);
|
|
371
|
+ }
|
|
372
|
+
|
|
373
|
+ while (inFile >> n) {
|
|
374
|
+ accum = accum + n;
|
|
375
|
+ }
|
|
376
|
+
|
|
377
|
+ cout << "Total: " << accum << endl;
|
|
378
|
+
|
|
379
|
+ inFile.close();
|
|
380
|
+```
|
|
381
|
+
|
|
382
|
+**Ejemplo 2**: Contar el número de líneas en un archivo que contiene un nombre por línea. Luego imprimir el contenido de la línea del medio.
|
|
383
|
+
|
|
384
|
+```
|
|
385
|
+ ifstream inFile;
|
|
386
|
+ string name;
|
|
387
|
+ int ctr = 0;
|
|
388
|
+
|
|
389
|
+ inFile.open("names.txt");
|
|
390
|
+
|
|
391
|
+ if (!inFile.is_open()) {
|
|
392
|
+ cout << "Error openning file names.txt\n";
|
|
393
|
+ exit(1);
|
|
394
|
+ }
|
|
395
|
+
|
|
396
|
+ while (inFile >> name) {
|
|
397
|
+ ctr++;
|
|
398
|
+ }
|
|
399
|
+
|
|
400
|
+ cout << "Total number of lines: " << ctr << endl;
|
|
401
|
+
|
|
402
|
+ // Estos dos comandos retroceden el file al principio.
|
|
403
|
+ inFile.clear();
|
|
404
|
+ inFile.seekg(0);
|
|
405
|
+
|
|
406
|
+ for (int i = 0; i <= ctr / 2; i++) {
|
|
407
|
+ inFile >> name;
|
|
408
|
+ }
|
|
409
|
+
|
|
410
|
+ cout << "The name at the position " << ctr / 2 << ": " << name << endl;
|
|
411
|
+
|
|
412
|
+ inFile.close();
|
|
413
|
+```
|
|
414
|
+
|
|
415
|
+---
|
|
416
|
+
|
|
417
|
+---
|
|
418
|
+
|
|
419
|
+
|
142
|
420
|
!INCLUDE "../../eip-diagnostic/PRMap/es/diag-prmap-01.html"
|
143
|
421
|
<br>
|
144
|
422
|
|