[vec1, vec2, vec3 ...] = textread(file_name, format {,n})
Fonction simple et efficace de lecture d'un fichier-texte nommé file_name dont l'ensemble des données répond à un format homogène. Les données peuvent être délimitées par un ou plusieurs espace, tab, voire même saut(s) de ligne newline. La lecture s'effectue ainsi en "format
libre" (comme avec sscanf et fscanf).
• Le vecteur-colonne vec1 recevra la 1ère "colonne" du fichier, le vecteur vec2 recevra la 2e colonne, vec3 la 3e, et ainsi de suite... La lecture s'effectue jusqu'à la fin du fichier, à moins que l'on spécifie le nombre n de fois que le format doit être réutilisé.
• Le nombre de variables vec1 vec2 vec3... et leurs types respectifs découlent directement du format
• Si vec-i réceptionne des chaînes de caractères, il sera de type "tableau cellulaire", en fait vecteur-colonne cellulaire
Les "spécifications de conversion" de format %f, %s, %u et %d peuvent être utilisées avec textread sous MATLAB et Octave. Sous Octave seulement on peut en outre utiliser les spécifications %o et %x.
Sous MATLAB, les spécifications %u et %d génèrent un vecteur réel double précision. Mais ATTENTION, sous Octave elles génèrent un vecteur entier 32 bits !
Sous MATLAB seulement on peut encore utiliser :
%[...] : lit la plus longue chaîne contenant les caractères énumérés entre [ ]
%[^...] : lit la plus longue chaîne non vide contenant les caractèrens non énumérés entre [ ]
Ex:
Soit le fichier-texte de données ventes.txt suivant : 10001 Dupond Livres 12 23.50 10002 Durand Classeurs 15 3.95 10003 Muller DVDs 5 32.00 10004 Smith Stylos 65 2.55 10005 Rochat CDs 25 15.50 10006 Leblanc Crayons 100 0.60 10007 Lenoir Gommes 70 2.00 et le script MATLAB/Octave suivant :
[No_client, Nom, Article, Nb_articles, Prix_unit] = textread('ventes.txt', '%f %s %s %f %f') ; Montant = Nb_articles .* Prix_unit ;
disp(' Client [No ] Nb Articles Prix unit. Montant ') disp(' --- --- --- --- --- ---') format = ' %10s [%d] %5d %-10s %8.2f Frs %8.2f Frs\n' ;
for no=1:1:length(No_client)
fprintf(format, Nom{no}, No_client(no), Nb_articles(no), Article{no}, Prix_unit(no), Montant(no) ) ; end
fprintf('\n\n TOTAL %8.2f Frs \n', sum(Montant) )
Attention : bien noter, ci-dessus, les accolades pour désigner éléments de Nom{} et de Article{}. Ce sont des "tableaux cellulaires" dont on pourrait aussi récupérer les éléments, sous forme de chaîne, avec : char(Nom(no)), char(Article(no)).
L'exécution de ce script: lit le fichier, calcule les montants, et affiche ce qui suit :
Client [No ] Nb Articles Prix unit. Montant --- --- --- --- --- --- Dupond [10001] 12 Livres 23.50 Frs 282.00 Frs Durand [10002] 15 Classeurs 3.95 Frs 59.25 Frs Muller [10003] 5 DVDs 32.00 Frs 160.00 Frs Smith [10004] 65 Stylos 2.55 Frs 165.75 Frs Rochat [10005] 25 CDs 15.50 Frs 387.50 Frs Leblanc [10006] 100 Crayons 0.60 Frs 60.00 Frs Lenoir [10007] 70 Gommes 2.00 Frs 140.00 Frs TOTAL 1254.50 Frs
Fonctions classiques de manipulation de fichiers (de type ANSI C)
file_id = fopen(file_name, mode)
[file_id, message_err ] = fopen(file_name, mode)
Ouvre le fichier de nom défini par la variable/chaîne file_name, et retourne l'identifiant file_id qui permettra de le manipuler par les fonctions décrites plus bas.
Si file_name ne définit qu'un nom de fichier, celui-ci est recherché dans le répertoire courant. Si l'on veut ouvrir un fichier se trouvant dans un autre répertoire, il faut bien entendu faire précéder le nom du fichier de son chemin d'accès (path) relatif ou absolu. S'agissant du séparateur de
répertoire, bien que celui-ci soit communément \ sous Windows, nous vous conseillons de toujours utiliser / (accepté par MATBAL/Octave sous Windows) pour que vos scripts/fonctions soient portables, c'est-à-dire utilisables dans les 3 mondes Windows, macOS et GNU/Linux.
Le mode d'accès au fichier sera défini par l'une des chaînes suivantes : • 'rt' ou 'rb' ou 'r' : lecture seule (read)
• 'wt' ou 'wb' ou 'w' : écriture (write), avec création du fichier si nécessaire, ou écrasement s'il existe • 'at' ou 'ab' ou 'a' : ajout à la fin du fichier (append), avec création du fichier si nécessaire • 'rt+' ou 'rb+' ou 'r+' : lecture et écriture, sans création
• 'wt+' ou 'wb+' ou 'w+' : lecture et écriture avec écrasement du contenu
• 'at+' ou 'ab+' ou 'a+' : lecture et ajout à la fin du fichier, avec création du fichier si nécessaire Le fait de spécifier t ou b ou aucun de ces deux caractères dans le mode a la signification suivante : • t : ouverture en mode "texte"
• b ou rien : ouverture en mode "binaire" (mode par défaut)
Sous Windows ou macOS, il est important d'utiliser le mode d'ouverture "texte" si l'on veut que les fins de ligne soient correctement interprétées !
9/14/2018
MATLAB et Octave - 7. Programmation : interaction, structures de contrôle, scripts, fonctions, entrées-sorties, debu…
https://enacit1.epfl.ch/cours_matlab/mfiles.shtml#editeur_debugger
17/22
En cas d'échec (fichier inexistant en lecture, protégé en écriture, etc...), file_id reçoit la valeur "-1". On peut aussi récupérer un message d'erreur sous forme de texte explicite sur message_err
Identifiants prédéfinis (toujours disponibles, correspondant à des canaux n'ayant pas besoin d'être "ouverts") :
• 1 ou stdout : correspond à la sortie standard (standard output, c'est-à-dire fenêtre console MATLAB/Octave), pouvant donc être utilisé pour l'affichage à l'écran
• 2 ou stderr : correspond au canal erreur standard (standard error, par défaut aussi la fenêtre console), pouvant aussi être utilisé par le programmeur pour l'affichage d'erreurs
• 0 ou stdin : correspond à l'entrée standard (standard input, c'est-à-dire saisie au clavier depuis console MATLAB/Octave).
Pour offrir à l'utilisateur la possibilité de désigner le nom et emplacement du fichier à ouvrir/créer à l'aide d'une fenêtre de dialogue classique (interface utilisateur graphique), on se référera aux fonctions uigetfile (lecture de fichier) et uiputfile (écriture de fichier) présentées au chapitre "Fenêtres de sélection de fichiers". Pour sélectionner un répertoire, on utilisera la fonction uigetdir.
[file_name, mode] = fopen(file_id)
Pour un fichier déjà ouvert avec l'identifiant file_id spécifié, retourne son nom file_name et le mode d'accès. freport()
Affiche la liste de tous les fichiers ouverts, avec file_id, mode et file_name. On voit que les canaux stdin, stdout et stderr sont toujours pré-ouverts {status=} fclose(file_id)
fclose('all')
Referme le fichier ayant l'identifiant file_id (respectivement tous les fichiers ouverts). Le status retourné est "0" en cas de succès, et "-1" en cas d'échec.
A la fin de l'exécution d'un script ayant ouvert des fichiers, tous ceux-ci sont automatiquement refermés, même en l'absence de fclose. variable = fscanf(file_id, format {,size})
[variable, count] = fscanf(file_id, format {,size})
Fonction de lecture formatée ("file scan formated") du fichier-texte spécifié par son identifiant file_id. Fonctionne de façon analogue à la fonction sscanf vue plus haut (à laquelle on renvoie le lecteur pour davantage de précision), sauf qu'on lit ici sur un fichier et non pas sur une chaîne de caractères.
Remarque importante : en l'absence du paramètre size (décrit plus haut sous sscanf), fscanf tente de lire (avaler, "slurp") l'intégralité du fichier (et non pas seulement de la ligne courante comme fgetl ou fgets).
Ex:
Soit le fichier-texte suivant : 10001 Dupond
Livres 12 23.50 10002 Durand
Classeurs 15 3.95
La lecture des données de ce fichier avec fscanf s'effectuerait de la façon suivante : file_id = fopen('fichier.txt', 'rt') ; no = 1 ; while ~ feof(file_id) No_client(no) = fscanf(file_id,'%u',1) ; Nom{no,1} = fscanf(file_id,'%s',1) ; Article{no,1} = fscanf(file_id,'%s',1) ; Nb_articles(no) = fscanf(file_id,'%u',1) ; Prix_unit(no) = fscanf(file_id,'%f',1) ; no = no + 1 ; end status = fclose(file_id) ; [variable, count] = scanf(format {,size})
Fonction spécifiquement Octave de lecture formatée sur l'entrée standard (donc au clavier, identifiant 0). Pour le reste, cette fonction est identique à fscanf.
line = fgetl(file_id)
Lecture, ligne par ligne ("file get line"), du fichier-texte spécifié par l'identifiant file_id. A chaque appel de cette fonction on récupère, sur la variable line de type chaîne, la ligne suivante du fichier (sans le caractère de fin de ligne).
string = fgets(file_id {,nb_car})
Lecture, par groupe de nb_car ("file get string"), du fichier-texte spécifié par l'identifiant file_id. En l'absence du paramètre nb_car, on récupère, sur la variable string, la ligne courante inclu le(s) caractère(s) de fin de ligne (<cr> <lf> dans le cas de Windows).
{count=} fskipl(file_id ,nb_lignes)
Avance dans le fichier file_id en sautant nb_lignes ("file skip lines"). Retourne le nombre count de lignes sautées (qui peut être différent de
nb_lignes si l'on était près de la fin du fichier).
{status=} feof(file_id)
Test si l'on a atteint la fin du fichier spécifié par l'identifiant file_id : retourne "1" si c'est le cas, "0" si non. Utile pour implémenter une boucle de lecture d'un fichier.
Ex: voir l'usage de cette fonction dans l'exemple fscanf ci-dessus frewind(file_id)
Se (re)positionne au début du fichier spécifié par l'identifiant file_id. Pour un positionnement précis à l'intérieur d'un fichier, voyez les fonctions :
• fseek(file_id, offset, origin) : positionnement offset octets après origin • position = ftell(file_id) : retourne la position courante dans le fichier {count=} fprintf(file_id, format, variable(s)... )
Fonction d'écriture formatée ("file print formated") sur un fichier-texte spécifié par l'identifiant file_id, et retourne le nombre count de caractères écrits. Fonctionne de façon analogue à la fonction sprintf vue plus haut (à laquelle on renvoie le lecteur pour davantage de précision), sauf qu'on écrit ici sur un fichier et non pas sur une chaîne de caractères.
{count=} fprintf(format, variable(s)... ) {count=} printf(format, variable(s)... )
Utiliser fprintf en omettant le file_id (qui est est identique à utiliser le file_id "1" représentant la sortie standard) ou printf (spécifique à Octave), provoque une écriture/affichage à l'écran (i.e. dans la fenêtre de commande MATLAB/Octave).
Ex: affichage de la fonction y=exp(x) sous forme de tableau avec :
x=0:0.05:1 ; exponentiel=[x;exp(x)] ; fprintf(' %4.2f %12.8f \n',exponentiel) {status=} fflush(file_id)
Pour garantir de bonnes performances, Octave utilise un mécanisme de mémoire tampon (buffer) pour les opérations d'écriture. Les écritures ainsi en attente sont périodiquement déversées sur le canal de sortie, au plus tard lorsque l'on fait un fclose. Avec la fonction fflush, on force le vidage (flush) du buffer sur le canal de sortie.
Dans des scripts interactifs ou affichant des résultats en temps réel dans la fenêtre console, il peut être utile dans certaines situations de flusher la sortie standard avec fflush(stdout). Voyez aussi la fonction page_output_immediately pour carrément désactiver le buffering.
Fonction textscan
Cette fonction est capable à la fois de lire un fichier ou de décoder une chaîne.
vec_cel = textscan(file_id, format {,n})
Lecture formatée d'un fichier-texte spécifié par l'identifiant file_id (voir ci-dessus) et dont l'ensemble des données répond à un format homogène.
La lecture s'effectue jusqu'à la fin du fichier, à moins que l'on spécifie le nombre n de fois que le format doit être réutilisé.
Dans le format, on peut notamment utiliser \r, \n ou \r\n pour matcher respectivement les caractères de fin de lignes "carriage-return" (macOS), "line-feed" (Unix/Linux) ou "carriage-return + line-feed (Windows)
La fonction retourne un vecteur-ligne cellulaire vec_cel dont la longueur correspond au nombre de spécifications du format. Chaque cellule contient un vecteur-colonne de type correspondant à la spécification de format correspondante.
Ex: on peut lire le fichier ventes.txt ci-dessus avec : file_id = fopen('ventes.txt', 'rt');
vec_cel = textscan(file_id, '%u %s %s %u %f'); fclose(file_id);
et l'on récupère alors dans vec_cel{1} le vecteur de nombre des No, dans vec_cel{2} le vecteur cellulaire des Clients, dans vec_cel{3} le vecteur cellulaire des Articles, etc...
vec_cel = textscan(string, format {,n}) Opère ici sur la chaîne string
7.8.5 Fonctions de lecture/écriture de fichiers spécifiques/binaires
fread(...) et fwrite(...)Fonctions de lecture/écriture binaire (non formatée) de fichiers, pour un stockage plus compact qu'avec des fichiers en format texte. Voyez l'aide pour davantage d'information.
xlsread(...) et xlswrite(...)
Fonctions de lecture/écriture de classeurs Excel (binaire). Voyez l'aide pour davantage d'information. odsread(...) et odswrite(...)
Fonctions de lecture/écriture de classeurs OpenOffice/LibreOffice (binaire). Voyez l'aide pour davantage d'information.
7.9 "Publier" un code MATLAB/Octave
7.9.1 La fonctionnalité "publish"
Se rapprochant du concept de notebook, la fonction publish permet d'exécuter un script MATLAB/Octave en produisant un rapport comportant 3 parties : le code source du script
les résultats d'exécution du script
les éventuels graphiques produits par le script
publish('script{.m}' {, 'format','fmt_rapport', 'imageFormat','fmt_images', 'showCode',true|false, 'evalCode',true|false } )
Le rapport est créé dans le sous-répertoire nommé "html", mais on peut désigner un autre répertoire avec 'outputDir', 'path' Les paramètres optionnels sont :
format : valeurs possibles : html, latex, doc, pdf (ce dernier nécessitant pdflatex c-à-d. texlive sous Linux) ; les valeurs par défaut sont : html sous MATLAB, latex sous Octave
imageFormat : valeurs possibles : png, jpg, pdf ; les valeurs par défaut sont : - si format html : png
- si format pdf : jpg
showCode : affichage du code dans le rapport, par défaut true
evalCode : exécution du code, par défaut true ; si mis à false, le code n'est pas exécuté et aucun graphique n'est bien évidement produit
grabcode('URL')
Récupère le code qui a été publié en HTML à l'URL spécifiée avec publish
Ex: Soit le script ci-dessous nommé code.m :
9/14/2018
MATLAB et Octave - 7. Programmation : interaction, structures de contrôle, scripts, fonctions, entrées-sorties, debu…
https://enacit1.epfl.ch/cours_matlab/mfiles.shtml#editeur_debugger
19/22
% Données
x= 4*rand(1,50) -2 % val. aléatoires entre -2 et +2 y= 4*rand(1,50) -2 % val. aléatoires entre -2 et +2 z= x.*exp(-x.^2 - y.^2) % Z en ces points
% Premier graphique (double, de type multiple plots) figure(1)
subplot(1,2,1) plot(x,y,'o')
title('semis de points aleatoire') grid('on')
axis([-2 2 -2 2]) axis('equal') subplot(1,2,2)
tri_indices= delaunay(x, y); % form. triangles => matr. indices trisurf(tri_indices, x, y, z) % affichage triangles
title('z = x * exp(-x^2 - y^2) % sur ces points') zlim([-0.5 0.5])
set(gca,'ztick',-0.5:0.1:0.5) view(-30,10)
% Second graphique (simple) figure(2)
xi = -2:0.2:2 ; yi = xi';
[XI,YI,ZI] = griddata(x,y,z,xi,yi,'nearest'); % interp. grille surfc(XI,YI,ZI)
title('interpolation sur grille')
publish('code.m', 'format','html', 'imageFormat','png')
produit le rapport accessible sous ce lien
7.9.2 Les noteboks Jupyter
Il s'agit d'une fonctionnalité moderne et extrêmement élégante que nous présentons dans un support de cours indépendant.
7.10 Debugging, profiling et optimisation de codes MATLAB/Octave
7.10.1 Debugging
Lorsqu'il s'agit de débuguer un script ou une fonction qui pose problème, la première idée qui vient à l'esprit est de parsemer le code d'instructions d'affichages intermédiaires. Plutôt que de faire des disp, on peut alors avantageusement utiliser la fonction warning présentée plus haut, celle-ci permettant en une seule instruction d'afficher du texte et des variables ainsi que de désactiver/réactiver aisément l'affichage de ces warnings. Mais il existe des fonctionnalités de debugging spécifiques présentées ci-après.