Problem mit ReadFile()



  • Wenn du unbedingt ReadFile nutzen willst, dann frag im WinAPI Forum. std::vector solltest du hier manueller Speicherverwaltung aber in jedem Fall vorziehen.

    Hast du schon mal die Rückgabewert der Funktion und GetLastError() getestet?

    Und warum willst du keine fstreams nutzen?



  • ich wette, readfile gibt einen wert != 0 zurück und bytesRead == 0.

    HANDLE benchFile = CreateFile(filename.c_str(),            
                                          GENERIC_WRITE | GENERIC_READ,
                                          FILE_SHARE_READ,
                                          NULL,
                                          CREATE_ALWAYS,
                                          FILE_ATTRIBUTE_NORMAL, // | FILE_FLAG_NO_BUFFERING,
                                          NULL);
    

    ->erstelle datei - geht nehme ich an?

    int filesize = 100 * MB; 
    char *filebuffer = new char [filesize]; 
    
    DWORD bytesWritten = 0;
    WriteFile(benchFile, filebuffer, filesize, &bytesWritten, NULL);
    cout << bytesWritten << endl;
    

    -> schreibt _irgendetwas_ in die datei hinein - geht nehme ich an?

    wir befinden uns am ende der datei.

    DWORD bytesRead = 0;
    ReadFile(benchFile, filebuffer, filesize, &bytesRead, NULL);
    cout << bytesRead << endl;
    

    ...und dort steht bekanntlich nichts mehr.

    ich finde nur keine funktion, die den pointer verschieben könnte - hab aber auch nur nach irgendwas mit "seek" gesucht.´
    sag doch erst mal, was du überhaupt willst.
    etwas in eine datei zu schreiben und genau das gleiche dann wieder auslesen zu wollen, ergibt - für mich - keinen sinn.

    bb


  • Mod

    lemon03 schrieb:

    Ich denke, die Antwort darauf würde zu weit führen und ich kann mir auch nicht recht vorstellen, das es für die Fehlersuche von Belang wäre. Sorry.

    Dann darfst du uns aber wenigstens deine Makroorgie und die Verwendung von new[] erklären. Insbesondere für letzteres kann es nun wirklich keine Gründe geben.

    Zu deinem Problem: Nun, es steht ja auch nichts drin an der Stelle in der Datei. Der Dateizeiger zeigt nach dem Schreiben hinter das geschriebene. Da du die Datei neu erstellst, kann an der Stelle logischerweise nichts mehr sein.

    edit: zu langsam.



  • Nun ... :

    Ich bin mit meinem C++ noch recht am Anfang und wollte mal versuchen einen kleinen Festplattenbenchmark zu schreiben. Angefangen habe ich mit put/get aber dort kamen unrealistische Werte raus und mir wurde gesagt, es sei reichlich ineffizient und ich solle CreateFile() und WriteFile/ReadFile nehmen oder zumindest write/read.

    Mit write/read kamen schon etwas realistischere Werte raus, nur beim Lesen kam ich immer auf über 1 GB/s. Mir wurde gesagt, der Grund wäre das Caching des OS und ich solle doch wirklich mal CreateFile nehmen, vielleicht auch mit dem Flag FILE_FLAG_NO_BUFFERING.

    Ich muss aber gestehen, das mir die WinAPI doch etwas schwer fällt, weshalb ich hier aufgeschlagen bin.

    Was ich möchte, ist ein File gewählter Größe schreiben, was dann wieder eingelesen wird, dann noch ein Kopiervorgang aus lesen und schreiben.

    Der Vorgang wird gemessen und wird in MB/s ausgegeben.

    char *filebuffer habe ich von meinen write/read Versuchen übernommen und da bei WriteFile() auch alles in Ordnung war, dachte ich, das das dann auch nicht falsch wäre.

    EDIT:

    Um zu zeigen, was ich bisher versucht habe, mein Versuch mit write/read:

    #include <iostream>
    //#include <string>
    #include <fstream>
    #include <cmath>
    #include <windows.h>
    #include <cstdio>  //für remove()
    
    using namespace std;
    
    const int MB = pow(2, 20);  //MegaByte
    const int GB = pow(2, 30);  //Gigabyte
    
    /*
    int prozent(int i, int filesize){
        int value = (i * 100) / filesize;
        return value;
    }
    */
    
    bool pruefePartition(char partChar){
        string testfile = ":/hdbench_test";
        testfile = partChar + testfile;
        ofstream file(testfile.c_str());
        if (!file){
            cout << "Fehler bei " << partChar << ":" << endl;
            return false;
        }
        file.close();
        remove(testfile.c_str());
        return true;
    }
    
    void schreibenFile(string bchfile, int filesize, char *filebuffer){
        ofstream file(bchfile.c_str(), ofstream::binary);
        file.write(filebuffer, filesize);
        file.close();
    }
    
    void lesenFile(string bchfile, int filesize, char *filebuffer){
        ifstream file(bchfile.c_str(), ifstream::binary);
        file.read(filebuffer, filesize);
        file.close();
    }
    
    void kopierenFile(string bchfile, int filesize, char *filebuffer){
        string bchfile_copy = bchfile + "_copy";
        ifstream file(bchfile.c_str(), ifstream::binary);
        ofstream file_copy(bchfile_copy.c_str(), ofstream::binary);
        file.read(filebuffer, filesize);
        file_copy.write(filebuffer, filesize);
        file_copy.close();
        file.close();
    }
    
    int main(){
    
        char partChar;  //Buchstabe der Partition
        do{
            do{
                cin.sync();
                cout << "Partition angeben (nur den Buchstaben): ";
                partChar = cin.get();
            }while ((partChar < 'A'  || partChar > 'z') && (!(partChar > 'Z' && partChar < 'a')));
        }while (!pruefePartition(partChar));
    
        cout << endl;
    
        string bchfile = ":/hdbench_file";  //Name des Benchfile
        bchfile = partChar + bchfile;
        int filesize = GB;  //Größe des Benchfile
        char *filebuffer = new char [filesize];  //Speicher für Benchfile reservieren
        LONGLONG frequency, curentCount, lastCount;  //Variablen für Zeitmessung
        QueryPerformanceFrequency((LARGE_INTEGER*) & frequency);  //Performance Counter holen
        double time_sec;  //Zeit in Sekunden
    
        cout << "messe Schreiben ..." << endl;
    
        QueryPerformanceCounter((LARGE_INTEGER*) & curentCount);  //1. Messung
        schreibenFile(bchfile, filesize, filebuffer);
        QueryPerformanceCounter((LARGE_INTEGER*) & lastCount);  //2. Messung
        time_sec = (((double)(lastCount - curentCount)) / ((double)frequency));  //Zeit in Sekunden ist Differenz von Messung 2 und Messung 1
        double time_write =  time_sec;
    
        cout << "messe Lesen ..." << endl;
    
        QueryPerformanceCounter((LARGE_INTEGER*) & curentCount);  //1. Messung
        lesenFile(bchfile, filesize, filebuffer);
        QueryPerformanceCounter((LARGE_INTEGER*) & lastCount);  //2. Messung
        time_sec = (((double)(lastCount - curentCount)) / ((double)frequency));  //Zeit in Sekunden ist Differenz von Messung 2 und Messung 1
        double time_read = time_sec;
    
        cout << "messe Kopieren ..." << endl;
    
        QueryPerformanceCounter((LARGE_INTEGER*) & curentCount);  //1. Messung
        kopierenFile(bchfile, filesize, filebuffer);
        QueryPerformanceCounter((LARGE_INTEGER*) & lastCount);  //2. Messung
        time_sec = (((double)(lastCount - curentCount)) / ((double)frequency));  //Zeit in Sekunden ist Differenz von Messung 2 und Messung 1
        double time_copy = time_sec;
    
        remove(bchfile.c_str());
        remove((bchfile + "_copy").c_str());
        delete filebuffer;
    
        int size_MB = filesize / MB;
        cout << endl;
        cout << size_MB << " MB geschrieben in Sekunden: " << time_write; cout.width(12); cout << "MB/s: " << size_MB / time_write << endl;
        cout << size_MB << " MB gelesen in Sekunden:     " << time_read; cout.width(12); cout << "MB/s: " << size_MB / time_read << endl;
        cout << size_MB << " MB kopiert in Sekunden:     " << time_copy; cout.width(12); cout << "MB/s: " << size_MB / time_copy << endl;
    
    }
    

    und mein aktueller Versuch:

    #include <iostream>
    //#include <string>
    //#include <fstream>
    #include <cmath>
    #include <windows.h>
    #include <cstdio>  //für remove()
    
    using namespace std;
    
    const int MB = pow(2, 20);  //MegaByte
    //const int GB = pow(2, 30);  //Gigabyte
    
    /*
    int prozent(int i, int filesize){
        int value = (i * 100) / filesize;
        return value;
    }
    */
    /*
    void schreibenFile(HANDLE benchFile, int filesize, char *filebuffer_out)
    {
        DWORD bytesWritten = 0;
        WriteFile(benchFile, filebuffer_out, filesize, &bytesWritten, NULL);
        //CloseHandle(benchFile);
    }
    */
    /*
    void lesenFile(HANDLE benchFile, int filesize, char *filebuffer_in)
    {
        DWORD bytesRead = 0;
        ReadFile(benchFile, filebuffer_in, filesize, &bytesRead, NULL);
        cout << bytesRead << endl;
    }
    */
    /*
    void kopierenFile(string bchfile, int filesize, char *filebuffer)
    {
        string bchfile_copy = bchfile + "_copy";
        ifstream file(bchfile.c_str(), ifstream::binary);
        ofstream file_copy(bchfile_copy.c_str(), ofstream::binary);
        file.read(filebuffer, filesize);
        file_copy.write(filebuffer, filesize);
        file_copy.close();
        file.close();
    }
    */
    
    int main(){
    
        string filename_proto = ":/hdbench_file";  //Name des Benchfile
        string filename;
        char partChar;  //Buchstabe der Partition
        bool partChar_true;  //Partitionsbuchstabe gültig?
        HANDLE benchFile;
    
        do{
            do{
                cin.sync();
                cout << "Partition angeben (nur den Buchstaben): ";
                partChar = cin.get();
            }while ((partChar < 'A'  || partChar > 'z') && (!(partChar > 'Z' && partChar < 'a')));
            filename = partChar + filename_proto;
            benchFile = CreateFile(filename.c_str(),            //Benchfile anlegen
                                          GENERIC_WRITE | GENERIC_READ,
                                          FILE_SHARE_READ,
                                          NULL,
                                          CREATE_ALWAYS,
                                          FILE_ATTRIBUTE_NORMAL, // | FILE_FLAG_NO_BUFFERING,
                                          NULL);
            if (benchFile == INVALID_HANDLE_VALUE){
                cout << "Fehler bei " << partChar << ":" << endl;
                partChar_true = false;
            }else{
                partChar_true = true;
            }
        }while (!partChar_true);
    
        cout << endl;
    
        int filesize = 100 * MB;  //Größe des Benchfile
        char *filebuffer = new char [filesize];  //Speicher für Benchfile reservieren
        LONGLONG frequency, curentCount, lastCount;  //Variablen für Zeitmessung
        QueryPerformanceFrequency((LARGE_INTEGER*) & frequency);  //Performance Counter holen
        double time_sec;  //Zeit in Sekunden
    
            cout << "messe Schreiben ..." << endl;
    
            //char *filebuffer_out = new char [filesize];  //Speicher für Benchfile reservieren
            DWORD bytesWritten = 0;
            QueryPerformanceCounter((LARGE_INTEGER*) & curentCount);  //1. Messun
            WriteFile(benchFile, filebuffer, filesize, &bytesWritten, NULL);
            cout << bytesWritten << endl;
            QueryPerformanceCounter((LARGE_INTEGER*) & lastCount);  //2. Messung
            time_sec = (((double)(lastCount - curentCount)) / ((double)frequency));  //Zeit in Sekunden ist Differenz von Messung 2 und Messung 1
            double time_write =  time_sec;
    
            cout << "messe Lesen ..." << endl;
    
            //char *filebuffer_in = new char [filesize];  //Speicher für Benchfile reservieren
            DWORD bytesRead = 0;
            QueryPerformanceCounter((LARGE_INTEGER*) & curentCount);  //1. Messung
            ReadFile(benchFile, filebuffer, filesize, &bytesRead, NULL);
            cout << bytesRead << endl;
            QueryPerformanceCounter((LARGE_INTEGER*) & lastCount);  //2. Messung
            time_sec = (((double)(lastCount - curentCount)) / ((double)frequency));  //Zeit in Sekunden ist Differenz von Messung 2 und Messung 1
            double time_read = time_sec;
    
    /*
            cout << "messe Kopieren ..." << endl;
    
            string filename_copy = filename +"_copy";
            HANDLE benchFile_copy = CreateFile(filename_copy.c_str(),            //Benchfile anlegen
                                          GENERIC_WRITE | GENERIC_READ,
                                          FILE_SHARE_READ,
                                          NULL,
                                          CREATE_ALWAYS,
                                          FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING,
                                          NULL);
    
            QueryPerformanceCounter((LARGE_INTEGER*) & curentCount);  //1. Messung
            kopierenFile(benchFile, benchfile_copy, filesize, filebuffer);
            QueryPerformanceCounter((LARGE_INTEGER*) & lastCount);  //2. Messung
            time_sec = (((double)(lastCount - curentCount)) / ((double)frequency));  //Zeit in Sekunden ist Differenz von Messung 2 und Messung 1
            double time_copy = time_sec;
    
    */
            CloseHandle(benchFile);
            //remove(filename.c_str());
            //remove((bchfile + "_copy").c_str());
            //delete filebuffer;
    
            int size_MB = filesize / MB;
            cout << endl;
            cout << size_MB << " MB geschrieben in Sekunden: " << time_write; cout.width(12); cout << "MB/s: " << size_MB / time_write << endl;
            cout << size_MB << " MB gelesen in Sekunden:     " << time_read; cout.width(12); cout << "MB/s: " << size_MB / time_read << endl;
            //cout << size_MB << " MB kopiert in Sekunden:     " << time_copy; cout.width(12); cout << "MB/s: " << size_MB / time_copy << endl;
    
    }
    

  • Mod

    Kurz gesagt: Du versuchst da gerade unfreiwillig, einen Benchmark für den Arbeitsspeicher zu schreiben.



  • Ja, das habe ich zumindest beim Lesen auch festgestellt. Beim Schreiben kommen so Werte um 120 MB/s raus, die auch tatsächliche Benchmarks anzeigen.

    Und ich hatte halt gehofft, mit CreateFile und ReadFile könnte ich das umgehen.



  • SeppJ schrieb:

    Kurz gesagt: Du versuchst da gerade unfreiwillig, einen Benchmark für den Arbeitsspeicher zu schreiben.

    Ich hab mich auch mal dran versucht... Meiner Meinung nach sollte das ja der richtige Weg sein:

    /*timer.hpp*/
    
    #include "windows.h"
    
    #include <cassert>
    #include <stdexcept>
    
    struct large_integer_t
    {
    	typedef __int64 integral_type;
    	operator float() const
    	{
    		return static_cast<float>( static_cast<integral_type>(*this) );
    	}
    
    	operator integral_type() const
    	{
    		return data.QuadPart;
    	}
    	operator integral_type()
    	{
    		return data.QuadPart;
    	}
    
    	large_integer_t()
    	:	data(LARGE_INTEGER())
    	{}
    
    	large_integer_t(const LARGE_INTEGER& data)
    	:	data(data)
    	{}
    
    	large_integer_t& operator-= (const large_integer_t& other)
    	{
    		data.QuadPart -= other.data.QuadPart;
    		return *this;
    	}
    private:
    	LARGE_INTEGER data;
    };
    
    large_integer_t operator- (const large_integer_t& lhs, const large_integer_t& rhs)
    {
    	large_integer_t tmp(lhs);
    	tmp -= rhs;
    	return tmp;
    }
    
    class timer_t
    {
    public:
    	typedef float second_t;
    
    	timer_t()
    	:	begin(get_timestamp())
    #if !defined (NDEBUG)
    	,	stopped(false)
    #endif //#if !defined (_NDEBUG)
    	{
    		end = begin;
    	}
    
    	void stop()
    	{
    #if !defined (NDEBUG)
    		stopped = true;
    #endif //#if !defined (_NDEBUG)
    
    		end = get_timestamp();
    	}
    
    	second_t get_seconds() const
    	{
    		assert(stopped);
    
    		return (end-begin)/static_cast<second_t>(get_frequency());
    	}
    
    private:
    #if !defined (NDEBUG)
    	bool stopped;
    #endif //#if !defined (_NDEBUG)
    
    	static large_integer_t get_frequency()
    	{
    		LARGE_INTEGER ret_val;
    		BOOL succeed = QueryPerformanceFrequency(&ret_val);
    
    		if(!succeed)
    			throw std::runtime_error("calling QueryPerformanceFrequency failed");
    
    		return ret_val;
    	}
    
    	static large_integer_t get_timestamp()
    	{
    		LARGE_INTEGER ret_val;
    		BOOL succeed = QueryPerformanceCounter(&ret_val);
    
    		if(!succeed)
    			throw std::runtime_error("calling QueryPerformanceCounter failed");
    
    		return ret_val;
    	}
    
    	large_integer_t begin;
    	large_integer_t end;
    };
    
    /*file_op.hpp*/
    
    #include "windows.h"
    
    #include <stdexcept>
    
    class file_t
    {
    public:
    	bool is_open() const
    	{
    		return fd != INVALID_HANDLE_VALUE;
    	}
    
    	bool bad() const
    	{
    		return !is_open() || op_failed;
    	}
    	bool good() const
    	{
    		return !bad();
    	}
    
    	void write(char* const first, std::size_t length)
    	{
    		if(bad())
    			return;
    
    		DWORD length_wrote;
    		BOOL succeeds = WriteFile(fd, first, static_cast<DWORD>(length), &length_wrote, NULL);
    
    		op_failed = !succeeds || (static_cast<std::size_t>(length_wrote) != length);
    	}
    
    	void read(char* first, std::size_t length)
    	{
    		if(bad())
    			return;
    
    		DWORD length_read;
    		BOOL succeeds = ReadFile(fd, first, static_cast<DWORD>(length), &length_read, NULL);
    
    		op_failed = !succeeds || (static_cast<std::size_t>(length_read) != length);
    	}
    
    	static file_t create(const char* filename)
    	{
    		HANDLE hwnd = CreateFile(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING, NULL);
    		return file_t(hwnd);
    	}
    	static file_t open(const char* filename)
    	{
    		HANDLE hwnd = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING, NULL);
    		return file_t(hwnd);
    	}
    	static void close(file_t& to_close)
    	{
    		if( !to_close.is_open() )
    			return;
    
    		CloseHandle(to_close.fd);
    		to_close.fd = INVALID_HANDLE_VALUE;
    	}
    private:
    	explicit file_t(HANDLE fd)
    	:	fd(fd), op_failed(false)
    	{}
    
    	HANDLE fd;
    	bool op_failed;
    };
    
    void delete_file(const char* filename)
    {
    	BOOL succeed = DeleteFile(filename);
    	if(!succeed)
    		throw std::runtime_error("cannot delete file");
    }
    
    /*main.cpp*/
    
    #include "timer.hpp"
    #include "file_op.hpp"
    
    template <class T, std::size_t n>
    std::size_t size_of(const T(&)[n])
    {
    	return n;
    }
    
    void do_and_print(const char* filename, std::size_t size_in_mb);
    
    #include <iostream>
    
    int main()
    {
    	const char* filenames[] =
    	{
    		"C:/tmp.txt",
    		"E:/tmp.txt",
    		"L:/tmp.txt",
    		"H:/tmp.txt"
    	};
    
    	std::size_t megabyte_count;
    	std::cout << "wie viele MB sollen jeweils gelesen/geschrieben werden?" << std::endl;
    	std::cin >> megabyte_count;
    
    	for(std::size_t i = 0; i != size_of(filenames); ++i)
    	{
    		std::cout << filenames[i] << std::endl;
    		do_and_print(filenames[i], megabyte_count);
    	}
    
    #if 0
    	std::cout << "Taste..." << std::endl;
    	std::cin.ignore();
    	std::cin.get();
    #endif
    }
    
    #include <algorithm>
    #include <iomanip>
    #include <vector>
    
    void do_and_print(const char* filename, std::size_t size_in_mb)
    {
    	if(size_in_mb == 0)
    		return;
    
    	std::ios_base::fmtflags flag_backup = std::cout.flags();
    	std::cout << std::setprecision(3) << std::fixed;
    
    	const std::size_t MB = 1024 * 1024;
    	const std::size_t buffer = size_in_mb * MB;
    
    	bool created_file = false;
    
    	std::vector<char> to_write(buffer, '1');
    	{
    		file_t file = file_t::create(filename);
    		created_file = file.is_open();
    		timer_t time;
    		file.write(&to_write[0], to_write.size());
    		time.stop();
    
    		if(file.bad())
    			std::cout << "schreiben fehlgeschlagen" << std::endl;
    		else
    			std::cout << "schreiben (" << size_in_mb << " MB): " << time.get_seconds() << "-> " << size_in_mb/time.get_seconds() << " MBps" << std::endl;
    
    		file_t::close(file);
    	}
    	std::vector<char> to_read(buffer, '0');
    
    	if(created_file)
    	{
    		file_t file = file_t::open(filename);
    		timer_t time;
    		file.read(&to_read[0], to_read.size());
    		time.stop();
    
    		if(file.bad())
    			std::cout << "lesen fehlgeschlagen" << std::endl;
    		else
    			std::cout << "    lesen (" << size_in_mb << " MB): " << time.get_seconds() << "-> " << size_in_mb/time.get_seconds() << " MBps" << std::endl;
    
    		file_t::close(file);
    	}
    
    	if(to_write != to_read)
    		std::cout << "kaputt ;)" << std::endl;
    
    	if(created_file)
    		delete_file(filename);
    
    	std::cout.flags(flag_backup);
    }
    
    wie viele MB sollen jeweils gelesen/geschrieben werden?
    C:/tmp.txt
    schreiben (5 MB): 0.162-> 30.818 MBps
        lesen (5 MB): 0.228-> 21.895 MBps
    E:/tmp.txt
    schreiben (5 MB): 0.180-> 27.835 MBps
        lesen (5 MB): 0.003-> 1495.359 MBps
    L:/tmp.txt
    schreiben (5 MB): 0.149-> 33.455 MBps
        lesen (5 MB): 0.054-> 92.113 MBps
    H:/tmp.txt
    schreiben (5 MB): 1.983-> 2.521 MBps
        lesen (5 MB): 0.253-> 19.797 MBps
    
    wie viele MB sollen jeweils gelesen/geschrieben werden?
    C:/tmp.txt
    schreiben (50 MB): 1.621-> 30.850 MBps
        lesen (50 MB): 1.769-> 28.257 MBps
    E:/tmp.txt
    schreiben (50 MB): 1.397-> 35.779 MBps
        lesen (50 MB): 0.035-> 1416.357 MBps
    L:/tmp.txt
    schreiben (50 MB): 1.222-> 40.904 MBps
        lesen (50 MB): 0.383-> 130.452 MBps
    H:/tmp.txt
    schreiben (50 MB): 5.537-> 9.030 MBps
        lesen (50 MB): 2.360-> 21.189 MBps
    
    wie viele MB sollen jeweils gelesen/geschrieben werden?
    C:/tmp.txt
    schreiben (200 MB): 6.472-> 30.902 MBps
        lesen (200 MB): 6.657-> 30.043 MBps
    E:/tmp.txt
    schreiben (200 MB): 6.053-> 33.041 MBps
        lesen (200 MB): 0.211-> 949.562 MBps
    L:/tmp.txt
    schreiben (200 MB): 4.585-> 43.617 MBps
        lesen (200 MB): 1.978-> 101.106 MBps
    H:/tmp.txt
    schreiben (200 MB): 26.159-> 7.645 MBps
        lesen (200 MB): 9.288-> 21.534 MBps
    

    C+E sind Partitionen auf ner uralten IDE Platte. Bei E ist die Komprimierung aktiviert, deshalb die utopischen Lese-Werte^^

    L ist nen RAID5 über 5 SATA Platten, da sollte aber einiges an Geschwindigkeit durch die Verschlüsselung verloren gehen. Und natürlich auch schon durch den Controller - aber der auf dem Board muss reichen, bis ich mal im Lotto gewonnen habe 😉

    H ist nen USB-Stick

    Scheint doch gar nicht mal so unrealistisch zu sein.

    bb

    so, das war jetzt das letzte edit - die einzige (für mich) offensichtliche schwäche liegt an der mangelnden fehlerbehandlung und dem fehlenden RAII für file - aber ich wollts auch nich total übertreiben^^



  • Also der Code hat mich schon beeindruckt 🙂 Leider ist er in meinen Augen so komplex, das ich ihn, oder Teile davon, nicht übernehmen kann. Ich habe nicht nur mit der WinAPI Schwierigkeiten, sondern schon mit der OOP 😞



  • den timer musst du nicht verstehen, der rest sollte aber auch für einen anfänger relativ gut zu verstehen sein?!

    wo liegt denn dein problem genau? oder beser: wo bist du denn in deinem buch und welches liest du denn?



  • Ich habe den 'Der C++ Programmierer' von Ulrich Breymann und bin im letzten Kapitel, bevor die OOP angeschnitten wird, genauer bei Programmstrukturierung.

    Und falls Du die timer.hpp meinst, da erkenne ich nur durch die cout-Ausgaben, das sie wohl mit der Zeitmessung zusammen hängt und just die funktioniert bei mir ja einwandfrei.



  • na gut, dann lies ma noch paar kapitel, dann wirst dus auch versthen 😉



  • Ich habe mal Dein Code bei mir kompilieren lassen und (ohne einen Zweifel gehabt zu haben ;)) die Werte waren auch bei mir realistisch.

    Gibt es einen Grund, warum Du Deine Headerfiles .hpp genannt hast? Die werden doch sonst immer nur .h genannt?



  • lemon03 schrieb:

    Ich habe mal Dein Code bei mir kompilieren lassen und (ohne einen Zweifel gehabt zu haben ;)) die Werte waren auch bei mir realistisch.

    Gibt es einen Grund, warum Du Deine Headerfiles .hpp genannt hast? Die werden doch sonst immer nur .h genannt?

    .hpp ist eine nette Abgrenzung zu C-Headern, wird fast öfters verwendet als .h



  • Wie macht man das denn in einer IDE? CodeBlocks zB bietet scheinbar nur h.files, cpp.files und leere Files an.

    Ich kann mir kaum vorstellen, das man die dann händisch umbenennt?



  • Ahja, inzwischen ist es mir eingefallen. Einfach bei leeres File *.hpp eingeben.


Anmelden zum Antworten