DMarlon Studio

Lección 19 · 19 de 20

Leer lo que se teclea · JavaScript

Lea datos de la entrada estándar en JavaScript con Node.js y fs.readFileSync(0), y conviértalos en un informe de notas.

JavaScript · Leer lo que se teclea en DMarlon Studio: el código del ejemplo y su salida en la terminal

En Node.js, lo que se teclea llega por la entrada estándar (stdin). require("fs") carga el módulo de archivos y `fs.readFileSync(0, "utf8")` lee toda la entrada de una vez como una cadena: el 0 es el número que identifica la entrada estándar.

Aquí la entrada viene de input.txt, que hace de teclado. En una terminal se ejecutaría con node main.js < input.txt, o bien escribiendo las líneas y pulsando Ctrl+D al final (Ctrl+Z y Intro en Windows).

Lo leído es un único texto, así que primero se corta en líneas con split("\n"). trim() quita los espacios y el \r que dejan los archivos de Windows, y filter descarta las líneas vacías.

Cada línea se separa en nombre y nota con split(" ") y desestructuración, y Number() convierte la nota en número. Los datos de fuera pueden venir mal: si la nota no es un número, `Number.isNaN()` lo detecta y continue salta la línea de Jorge con un aviso.

Con los alumnos ya en un array de objetos, el informe es lo de las lecciones anteriores: un ternario para el resultado, padEnd y padStart para las columnas y reduce para la media.

Código · main.js

// Read everything typed on the keyboard (stdin) as one string.const fs = require("fs");const input = fs.readFileSync(0, "utf8");// Split it into lines and drop the empty ones.const lines = input.split("\n").map((l) => l.trim()).filter((l) => l !== "");console.log(`Read ${lines.length} lines`);// Each line has a name and a grade separated by a space.const students = [];for (const line of lines) {  const [name, gradeText] = line.split(" ");  const grade = Number(gradeText);  if (Number.isNaN(grade)) {    console.log(`Skipping "${line}": the grade is not a number`);    continue;  }  students.push({ name, grade });}// A small report with what we have read.for (const { name, grade } of students) {  const result = grade >= 5 ? "passed" : "failed";  console.log(`${name.padEnd(6)} ${grade.toFixed(2).padStart(5)}  ${result}`);}const sum = students.reduce((acc, s) => acc + s.grade, 0);console.log("Class average:", (sum / students.length).toFixed(2));

Entrada (lo que se teclea) · input.txt

Ana 7.5
Luis 4
Jorge absent
Marta 9
Pablo 6.25

Salida · node main.js

Read 5 lines
Skipping "Jorge absent": the grade is not a number
Ana     7.50  passed
Luis    4.00  failed
Marta   9.00  passed
Pablo   6.25  passed
Class average: 6.69

Para recordar

  • fs.readFileSync(0, "utf8") lee toda la entrada estándar.
  • split("\n") la corta en líneas; trim limpia cada una.
  • Number() convierte texto en número; compruébelo con Number.isNaN.
  • No se fíe de los datos de fuera: valídelos.

Ejercicio

Cambie input.txt para que cada línea tenga un nombre y tres notas, calcule la media de cada alumno y diga cuál tiene la más alta.