5 oder mehr dateien in eine schreiben, aber mit abfrage der .....
-
einzulesenden dateien.
Hallo,
ich hab schon lang kein c++ mehr programmiert und bin ein bischen eingerostet.
Ich müsste ein Programm schreiben, dass mehrere Dateien einliest.
z.B: sind unsere daten immer mit datum durchnummeriert. zb:heute 061906dv.dat.
ich sollte nun eine ein wochendatei, eine zwei, drei und vier wochendatei machen.
welchen befehle benötige ich oder aber wie muss ich das schreiben, dass mein kollege eingibt zb für die 2 wochendatei : 070106dv.dat bis 210106dv.dat und das programm nur diese daten einliest und aus diesen eine macht.
fürs anhängen werd ich ios_app brauchen, aber was brauch ich fürs einlesen mit der eingabe?
Bitte helft mir!
-
Du mußt die Dateien eine nach der anderen öffnen, einlesen und dann hintereinander rausschreiben:
vector<string> namen;// dort alle Dateinamen eintragen ifstream fin; ofstream fout("Woche.dat"); for(int i=0;i<namen.size();++i) { fin.open(namen[i].c_str()); //kopiere fin nach fout fin.close(); }
-
cool.
aber kann ich auch ne eingabe programmieren, wo mein kollege die anfangsdatei (z.B 1.dat) und die enddatei (7.dat) reintippen kann und das programm alle dazwischen miteinliest?Das könnte man zwar in ner for schleifen einfach hochzählen lassen, aber wie oben beschrieben, zählen sich meine dateien
200106dv.dat
210106dv.dat
220106dv.datso nach oben. datumsmäßig.
wie soll ich denn das machen?
-
Wenn du weißt, wie sich deine Namen zusammensetzen, geht das sicher, dort einen Bereich festzulegen. In deinem Beispiel sieht es so aus, als ob du dort Datumsbereiche verwendest, da könnten die Funkionen aus der <ctime> weiterhelfen. (z.B. könntest du das Start- und Endedatum in einer struct_tm unterbringen und mit strftime() daraus deine Dateinamen erzeugen)
-
yo, das hört sich gut an.
ich werd ab montag mal anfangen.
wenn ich nich weiterweiß, kann ich ja posten und mit deiner hilfe rechnen ,oder?
Bittebitte...
Mfg
und schönes we
-
urkman schrieb:
welchen befehle benötige ich oder aber wie muss ich das schreiben, dass mein kollege eingibt zb für die 2 wochendatei : 070106dv.dat bis 210106dv.dat und das programm nur diese daten einliest und aus diesen eine macht.
Mal angenommen, da wäre ein Klasse Datum, die man hochzählen und vergleichen kann und von der man den passenden Datum-Sting bekommt, um den Dateinamen zu erzeugen. Dann könnte eine Funktion, die alle Dateien in eine steckt etwa so aussehen:
void merge_files( Datum dat, const Datum& bis, const std::string& zielname ) { std::ofstream ziel( zielname.c_str() ); ziel.exceptions( std::ios_base::failbit ); // Ex bei Fehler for( ; dat <= bis; ++dat ) { const std::string dateiname = dat.str() + "dv.dat"; // Format "TTMMJJdv.dat" std::ifstream in( dateiname.c_str() ); if( !in.is_open() ) { std::cerr << dateiname << " nicht gefunden" << std::endl; continue; } ziel << in.rdbuf(); // Datei kopieren std::cout << dateiname << " hinzugefuegt" << std::endl; } std::cout << "Ziel: " << zielname << std::endl; }das sieht so kompliziert nciht aus - oder? Bleibt also noch Datum. Wir brauchen:
- einen Konstruktor, der aus dem Text "TTMMJJ" ein 'Datum' macht
- einen Vergleichsoperator
- einen operator++ um zum nächsten Tag zu kommen
- eine Methode str() um den Datums-String zu generieren// -- zum Herausholen der einzelnen int's aus dem String int substring_to_int( const std::string& txt, unsigned off, unsigned len ) { int x; std::stringstream strm( txt.substr( off, len ) ); if( (strm >> x).fail() || !strm.eof() ) throw std::runtime_error( "Text enthält keine Zahl" ); return x; } struct Datum { // -- 'txt' enthält das Datum im Format "TTMMJJ" explicit Datum( const char* txt ) : m_jahr( substring_to_int( txt, 4, 2 ) ) , m_monat( substring_to_int( txt, 2, 2 ) ) , m_tag( substring_to_int( txt, 0, 2 ) ) { if( m_monat < 1 || m_monat > 12 ) throw std::runtime_error( "Monat liegt ausserhalb des Intervalls [1,12]" ); if( m_tag < 1 || m_tag > max_tage() ) throw std::runtime_error( "der Tag ist <1 oder groesser als die Anzahl der Tage in diesem Monat" ); } // -- zum nächsten Tag Datum& operator++() { if( ++m_tag > max_tage() ) { m_tag = 1; if( ++m_monat > 12 ) { m_monat = 1; // Januar ++m_jahr; } } return *this; } // -- liefert das Datum im Format "TTMMJJ" std::string str() const { using namespace std; stringstream txt; txt << setfill( '0' ) << setw( 2 ) << m_tag << setw( 2 ) << m_monat << setw( 2 ) << m_jahr; return txt.str(); } bool operator<( const Datum& b ) const { return std::make_pair( m_jahr, std::make_pair( m_monat, m_tag) ) < std::make_pair( b.m_jahr, std::make_pair( b.m_monat, b.m_tag) ); } // -- liefert die max. Anzahl von Tagen für den akt. Monat (und Jahr) int max_tage() const { // ggf. assert( m_monat >= 1 && m_monat <= 12 ); const int n_tage[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; if( m_monat == 2 && m_jahr % 4 == 0 ) return 29; // 29. Februar return n_tage[ m_monat - 1 ]; } private: int m_jahr; int m_monat; int m_tag; }; bool operator<=( const Datum& a, const Datum& b ) { return !( b < a ); }.. dann brauch es doch nur noch ein main:
int main( int argc, char* argv[] ) { try { if( argc != 3 ) { std::cout << "2 Parameter angeben " << std::endl; return -1; } merge_files( Datum( argv[1] ), Datum( argv[2] ), ziel_datei( argv[1], argv[2] ) ); return 0; } catch( const std::exception& err ) { std::cerr << "Fehler: " << err.what() << std::endl; } return -1; }Wobei Du Dir noch Gedanken machen darfst, wie der Name der Ziel-Datei generiert wird.
std::string ziel_datei( const char* von, const char* bis ) { return std::string( von ) + "_" + std::string( bis ) + ".dat"; }Folgende Includes sind notwendig, damit alles compiliert
#include <iostream> #include <fstream> #include <iomanip> // setfill, setw #include <sstream> #include <utility> // make_pairGruß
Werner
-
wow, danke!. ich klemm mich ab morgen dahinter und eld mich dann.
1000 Dank!