Pour les détails quant à cette démarche et pour des liens vers les autres questions : index.html#profquiz.
Pour un rappel des principes : index.html#profquiz_principes
Pour cette question, les solutionnaires suivants sont disponibles :
Rédigez un programme qui (a) lit le nom d'un fichier (on présume ici un fichier texte), (b) ouvre un fichier en sortie dont le nom sera "Sortie - NOM" où NOM est le nom du fichier en entrée (extension incluse) et qui copie chaque ligne du fichier en entrée dans le fichier en sortie. Assurez-vous que tous les fichiers soient proprement fermés quoi qu'il arrive. Source : ceci est une partie d'un travail donné à la session 2 au SIM à l'hiver 2013, en C#.
En C#, une solution correcte et accessible pour les étudiant(e)s de S2 (pour qui ce problème a été pensé) serait :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace z10
{
class Program
{
static void Main(string[] args)
{
Console.Write("Nom du fichier? ");
string nomFichier = Console.ReadLine();
if (nomFichier.Length > 0)
{
StreamReader lecteur = null;
try
{
lecteur = new StreamReader(nomFichier);
string nomSortie = string.Format("Sortie - {0}", nomFichier);
StreamWriter scripteur = null;
try
{
scripteur = new StreamWriter(nomSortie);
while (!lecteur.EndOfStream)
{
string ligne = lecteur.ReadLine();
scripteur.WriteLine(ligne);
}
}
catch (Exception)
{
Console.WriteLine("Erreur étrange en écriture");
lecteur.Close();
}
finally
{
if (scripteur != null)
{
scripteur.Close();
}
}
}
catch (FileNotFoundException)
{
Console.WriteLine("Le fichier {0} est introuvable", nomFichier);
}
finally
{
if (lecteur != null)
{
lecteur.Close();
}
}
}
}
}
}
Ce code repose beaucoup sur la structure try...catch...finally, et dépend d'initialisations à null au préalable pour les références finalisées dans les blocs finally, donc d'une compréhension à tout le moins superficielle des références. La paire ReadLine()/ WriteLine() ne devrait pas poser de problème à des débutants, puisqu'elle correspond superficiellement aux entrées/ sorties à la console. La similitude entre lire et écrire dans un fichier et lire et écrire à la console est à tout le moins un indice des avantages de l'approche objet : on peut l'amener de manière superficielle (niveau : utilisation) ou en profondeur (niveau : compréhension) en fonction du moment et de la clientèle.
En C++, une solution correcte et accessible pour les étudiant(e)s de S2 (pour qui ce problème a été pensé) serait :
#include <string>
#include <fstream>
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
string fichierEntree;
if (getline(cin, fichierEntree) && !fichierEntree.empty())
{
ifstream in(fichierEntree);
if (in)
{
ofstream out("Sortie - " + fichierEntree);
string ligne;
while (getline(in, ligne))
out << ligne << endl;
}
else
cerr << "Le fichier " << fichierEntree << " est introuvable" << endl;
}
}
Ce code repose beaucoup sur le fait que la lecture sur un flux retourne une référence sur le flux, et que ce flux se teste comme un booléen. En S1 et en S2, ce genre de truc passe mieux comme une recette (niveau : utilisation). La similitude entre lire et écrire dans un fichier et lire et écrire à la console est à tout le moins un indice des avantages de l'approche objet : on peut l'amener de manière superficielle (niveau : utilisation) ou en profondeur (niveau : compréhension) en fonction du moment et de la clientèle. En C++, les entrées / sorties sur des flux ne lèvent pas d'exceptions (il est possible de modifier ce comportement, mais ce n'est pas idiomatique au langage), ce qui élimine cette considération dans le code en exemple.