// This file is part of the Herezh++ application. // // The finite element software Herezh++ is dedicated to the field // of mechanics for large transformations of solid structures. // It is developed by Gérard Rio (APP: IDDN.FR.010.0106078.000.R.P.2006.035.20600) // INSTITUT DE RECHERCHE DUPUY DE LÔME (IRDL) . // // Herezh++ is distributed under GPL 3 license ou ultérieure. // // Copyright (C) 1997-2022 Université Bretagne Sud (France) // AUTHOR : Gérard Rio // E-MAIL : gerardrio56@free.fr // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, // or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . // // For more information, please consult: . #include //#ifdef SYSTEM_MAC_OS_X // #include // a priori ce n'est pas portable //#el #if defined SYSTEM_MAC_OS_CARBON #include // a priori ce n'est pas portable #else #include // pour le flot en memoire centrale #endif #include //#include "Debug.h" #ifndef ENLINUX_STREAM #include #else #include #include #endif #include "UtilLecture.h" using namespace std; // // ----- routine de la classe UtilLecture ------- // // routine pour acquerir un nouvel enregistrement et // passer les commentaires dans les fichiers d'entree d'herezh // Un commentaire se trouve apres le symbole # // une ligne est consideree comme non_commentaire si elle possede au moins un carractere non // identique a l'espace avant le carractere # // dans le cas ou il y a une erreur de lecture ou que la fin de fichier est ateinte // le programme genere une exception de tye : errNouvelEnreg, =1 -> fin de fichier // = -1 autre probleme de lecture void UtilLecture::Nouvel_enreg() { char delim = '\n'; // fin de ligne utilise int nouvelleligne = 0; /* initialisation de l'indicateur pour sortie de la boucle de recherche, quand = 1 on a trouve une ligne interessante */ char* fin = NULL ; // position du carractere # char* lienLigne = NULL; // position éventuelle d'un caractère \ de continuation de ligne unix bool suiteLigne = false; // indique si oui ou non la ligne lue se continue char* finReturn = NULL; // position éventuelle d'un caractère \r (cariage return) ifstream & fichier = *ptrfich; tabMultiLignes[0] = '\0'; // on met à 0 le tableau de stockage de plusieurs lignes do // on test jusqu'a une ligne interessante { suiteLigne=false; fichier.getline(tableau,longueur,delim); // lecture d'une ligne dans le fichier // reta = -1 s'il y a eu un pb qui fait qu'aucune lecture viable n'a été faite (maille1->numLigne)++; // incrementation du numero de ligne /*// -- debug if (fichier.eof() && (reta != -1) ) cout << "\n ** debug UtilLecture::Nouvel_enreg() " << " fichier.rdstate()= "<< fichier.rdstate() << endl; */// -- fin debug // ---- traitement d'un cas particulier que je ne vois pas comment traiter autrement int long_ligne = 0; // une longeur de ligne intermédiaire, ne sert que pour le test plus bas if ( (fichier.rdstate() != 6) && fichier.eof()) // on a atteind la fin de ligne, long_ligne = (int) strlen (tableau); // mais on a lue quelque chose /* pour mémoire: enum io_state { badbit = 1<<0, // -> 1 dans rdstate() eofbit = 1<<1, // -> 2 failbit = 1<<2, // -> 4 goodbit = 0 // -> O }; rdstate() == 6 cela signifie eofbit + failbit */ // test de l'etat du flux d'entree if (( fichier.rdstate() == 0 ) // cas normal || (long_ligne > 0 ) // cas où on a quand même lue quelque chose ) // car reta != -1, mais que l'on a atteind la fin de ligne { int finLigne = (int) strlen (tableau); // longueur de la ligne (surabondant / à // long_ligne mais on garde pour ne pas mélanger if ( finLigne > 0 ) { // cas d'une ligne non vide fin = strchr(tableau,'#'); // position du debut de commentaire s'il existe finReturn = strchr(tableau,'\r'); // position d'un "cariage return" s'il existe if (finReturn != NULL) { // on supprime le caractère pour pas que cela pose des pb par la suite *finReturn = '\0'; }; lienLigne = strchr(tableau,'\\'); // position du caractère de continuation de ligne if ( (lienLigne != NULL) && // on n'intervient que s'il y a un caractère de continuation ( ((fin != NULL) && (lienLigne < fin)) // si le caractère de continuation est après un #, on n'en tient pas compte || (fin == NULL) // sinon on en tiens compte ) ) { // on supprime le caractère pour pas que cela pose des pb par la suite mais on sait avec lienLigne que // la ligne continue *lienLigne = '\0'; suiteLigne = true; //cout << "\n on a trouvé un antislash !! "; //Sortie(1); } else if ( (lienLigne != NULL) && // on n'intervient que s'il y a un caractère de continuation ((fin != NULL) && (lienLigne > fin)) ) { // on supprime le caractère pour pas que cela pose des pb par la suite mais on sait avec lienLigne que // la ligne continue *lienLigne = '\0'; suiteLigne = false;lienLigne=NULL; //cout << "\n on a trouvé un antislash !! "; //Sortie(1); }; char* ptr = tableau; // initialisation de la boucle do dans le if else suivant int debut = -1; // indiquera le premier caractère non nul // on cherche un carractere different de l'espace if ((fin != NULL)&&(fin != tableau) ) // cas ou il y a un # { do { // on cherche jusqu'a un // if (*ptr != ' ') // carractere non espacement if ((*ptr != ' ') &&(*ptr != '\t')&&(*ptr != '\0')) // carractere non espacement et non tabulation nouvelleligne = 1 ; // ptr++; debut++; } while ((nouvelleligne == 0)&&(ptr <= fin-1)); if (nouvelleligne == 1) // sortie de la ligne interessante { // mise à nul du tableau tablcar // nouvelle méthode: on se contente de mettre un caractère nul après la zone lue //essai---------------- for (int ii =0; ii<= longueur; ii++) tablcar[ii] = '\0'; // recopie uniquement à partir du premier caractère non nul int ii,ii2; for (ii =debut,ii2=0; ii<= (int) (fin - tableau) -1; ii++,ii2++) // for (ii =debut,ii2=0; ii<= ((int) fin - (int) tableau) -1; ii++,ii2++) tablcar[ii2] = tableau[ii]; // on met un caractère de fin de chaine tablcar[ii2]='\0'; // suppression des caractères nuls et des tabulations de fin de ligne for (int ii3 = ii2-1; ii3 >= 0; ii3--) // if (tablcar[ii3] == ' ') tablcar[ii3] = '\0'; else break; if ((tablcar[ii3] == ' ') || (tablcar[ii3] == '\t')) tablcar[ii3] = '\0'; else break; }; } else if (fin != tableau) // cas ou la ligne ne contiend pas de # { do { // on cherche jusqu'a un // if (*ptr != ' ') // carractere non espacement if ((*ptr != ' ') &&(*ptr != '\t')&&(*ptr != '\0')) // carractere non espacement et non tabulation nouvelleligne = 1 ; // ptr++;debut++; } while ((nouvelleligne == 0)&&(ptr <= tableau + finLigne-1)); if (nouvelleligne == 1) // sortie de la ligne interessante { // mise à nul du tableau tablcar // nouvelle méthode: on se contente de mettre un caractère nul après la zone lue //essai---------------- for (int ii =0; ii<= longueur; ii++) tablcar[ii] = '\0'; // recopie uniquement à partir du premier caractère non nul // jusqu'au caractère int ii,ii2; for (ii =debut,ii2=0; ii<= finLigne-1; ii++,ii2++) tablcar[ii2] = tableau[ii]; // on met un caractère de fin de chaine tablcar[ii2]='\0'; // suppression des caractères nuls de fin de ligne for (int ii3 = ii2-1; ii3 >= 0; ii3--) if (tablcar[ii3] == ' ') tablcar[ii3] = '\0'; else break; }; }; }; // sinon cas d'une ligne vide, on passe a la suivante } else { // traitement des erreurs du flux d'entree // if ( fichier.eofbit == 1 ) #ifndef ENLINUX_STREAM if ( (fichier.rdstate() & ios_base::eofbit) == ios_base::eofbit) #else if ( (fichier.rdstate() & ios::eofbit) == ios::eofbit) #endif { ErrNouvelEnreg sortie(1) ; // fin du fichier atteind throw (sortie); nouvelleligne = 1; } else { ErrNouvelEnreg sortie(-1) ; // probleme de lecture indetermine throw (sortie); // erreur de lecture nouvelleligne = 1; } }; // dans le cas où il y a un caractère de continuation on sauvegarde le résultat et on continue if ((suiteLigne) || (tabMultiLignes[0] != '\0')) // cas ou on a lue un caractère de continuation { //ou bien que l'on lit la dernière ligne d'une suite strcat(tabMultiLignes,tablcar); }; }while ((nouvelleligne == 0 ) || (suiteLigne)); // on boucle tant qu'il n'y a rien dans la ligne et qu'il n'y a pas de caractère de continuation // dans le cas ou le tableau tabMultiLignes a été utilisé on recopie le résultat dans tabcar if (tabMultiLignes[0] != '\0') strcpy(tablcar,tabMultiLignes); //--pour la mise au point //cout << "\n " << tablcar ; //--fin mise au point }; // // ----- routine de la classe UtilLecture ------- // // même routine que nouvel enreg, mais pour la lecture des commandes de visualisation // On utilise grosso modo une struture simplifiée de nouvel_enreg car ici il n'y a pas de fichier // Imbriqué // Permet de passer les commentaires dans le fichier d'entree // Un commentaire se trouve apres le symbole # // une ligne est consideree comme non_commentaire si elle possede au moins un carractere non // identique a l'espace avant le carractere # // dans le cas ou il y a une erreur de lecture ou que la fin de fichier est ateinte // le programme genere une exception de tye : errNouvelEnreg, =1 -> fin de fichier // = -1 autre probleme de lecture void UtilLecture::Nouvel_enregCvisu () { char delim = '\n'; // fin de ligne utilise int nouvelleligne = 0; // initialisation de l'indicateur pour sortie de la boucle //de recherche, quand = 1 on a trouve une ligne interessante char* fin ; // position du carractere # fstream & fichier = *ent_CommandeVisu; int numLigne=0; // numéro de la ligne courante en lecture do // on test jusqu'a une ligne interessante { fichier.getline(tableauCVisu,longueur,delim); // lecture d'une ligne dans le fichier numLigne++; // incrementation du numero de ligne if ( fichier.rdstate() == 0 ) // test de l'etat du flux d'entree { int finLigne = (int) strlen (tableauCVisu); // longueur de la ligne if ( finLigne > 0 ) { // cas d'une ligne non vide fin = strchr(tableauCVisu,'#'); // position du debut de commentaire s'il existe char* ptr = tableauCVisu; // initialisation de la boucle do dans le if else suivant int debut = -1; // indiquera le premier caractère non nul // on cherche un carractere different de l'espace if ((fin != NULL)&&(fin != tableauCVisu) ) // cas ou il y a un # { do { // on cherche jusqu'a un if (*ptr != ' ') // carractere non espacement nouvelleligne = 1 ; // ptr++; debut++; } while ((nouvelleligne == 0)&&(ptr <= fin-1)); if (nouvelleligne == 1) // sortie de la ligne interessante { // mise à nul du tableauCVisu tablcarCVisu // nouvelle méthode: on se contente de mettre un caractère nul après la zone lue //essai---------------- for (int ii =0; ii<= longueur; ii++) tablcarCVisu[ii] = '\0'; // recopie uniquement à partir du premier caractère non nul int ii,ii2; for (ii =debut,ii2=0; ii<= (int) (fin - tableauCVisu) -1; ii++,ii2++) // for (ii =debut,ii2=0; ii<= ((int) fin - (int) tableauCVisu) -1; ii++,ii2++) tablcarCVisu[ii2] = tableauCVisu[ii]; // on met un caractère de fin de chaine tablcarCVisu[ii2]='\0'; // suppression des caractères nuls de fin de ligne for (int ii3 = ii2-1; ii3 >= 0; ii3--) if (tablcarCVisu[ii3] == ' ') tablcarCVisu[ii3] = '\0'; else break; }; } else if (fin != tableauCVisu) // cas ou la ligne ne contiend pas de # { do { // on cherche jusqu'a un if (*ptr != ' ') // carractere non espacement nouvelleligne = 1 ; // ptr++;debut++; } while ((nouvelleligne == 0)&&(ptr <= tableauCVisu + finLigne-1)); if (nouvelleligne == 1) // sortie de la ligne interessante { // mise à nul du tableauCVisu tablcarCVisu for (int ii =0; ii<= longueur; ii++) tablcarCVisu[ii] = '\0'; // recopie uniquement à partir du premier caractère non nul // jusqu'au caractère int ii,ii2; for (ii =debut,ii2=0; ii<= finLigne-1; ii++,ii2++) tablcarCVisu[ii2] = tableauCVisu[ii]; // suppression des caractères nuls de fin de ligne for (int ii3 = ii2-1; ii3 >= 0; ii3--) if (tablcarCVisu[ii3] == ' ') tablcarCVisu[ii3] = '\0'; else break; }; }; }; // sinon cas d'une ligne vide, on passe a la suivante } else { // traitement des erreurs du flux d'entree // if ( fichier.eofbit == 1 ) #ifndef ENLINUX_STREAM if ( (fichier.rdstate() & ios_base::eofbit) == ios_base::eofbit) #else if ( (fichier.rdstate() & ios::eofbit) == ios::eofbit) #endif { ErrNouvelEnregCVisu sortie(1) ; // fin du fichier atteind throw (sortie); nouvelleligne = 1; } else { ErrNouvelEnregCVisu sortie(-1) ; // probleme de lecture indetermine throw (sortie); // erreur de lecture nouvelleligne = 1; } }; // dans le cas }while (nouvelleligne == 0 ) ; };