<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Datei einlesen und in Structvektor schreiben]]></title><description><![CDATA[<p>Hallo an alle,</p>
<p>ich versuche mich gerade an einem Programm, mit dem ich historische Kursdaten aus .csv Dateien einlese, um damit noch weitere Sachen zu machen (die erstmal unwichtig sind).</p>
<p>Ich wollte einfach mal wissen, was ihr davon haltet, was ich bisher geschrieben habe. Das ist sicherlich keine ideale Lösung, aber hauptsache es funktioniert.</p>
<p>main.cpp:</p>
<pre><code>#include &lt;iostream&gt;
#include &lt;fstream&gt;
#include &lt;string&gt;
#include &lt;vector&gt;
#include &quot;Day.h&quot;

std::ifstream file;    //Die Datei
std::vector&lt;Day&gt; chartdata;

//Open File
void openfile()
{
    file.open(&quot;table.csv&quot;);		//file.csv wird geöffnet
    if(!file.is_open())			//Fehlermeldung   
        std::cerr &lt;&lt; &quot;Fehler beim Öffnen!&quot; &lt;&lt; std::endl;

	size_t    pos;
    std::string search;
    search = &quot;Adj Close&quot;;		//Letzte Spaltenüberschrift, um an den Anfang der 2. Zeile zu gelangen
    std::string line;			//Zum Überspringen der Überschriften
    //Überspringe die Überschriften und setze den Cursor auf das erste Datum
	getline(file, line);        //1. Zeile in line schreiben
    pos = line.find(search);    //suche den String search
    file.seekg(pos + search.length() + 1);			//Setze Cursor hinter die Überschrift

}

std::istream&amp; readdata(Day&amp; day)
{
    getline(file, day.date, ',');
    getline(file, day.open, ',');
    getline(file, day.high, ',');
    getline(file, day.low, ',');
    getline(file, day.close, ',');
    getline(file, day.volume, ',');
    getline(file, day.adjclose, '\n');
    return file;
}

//Read File
void readfile()
{
	chartdata.resize(1);
	for(int i = 0; file.good();i++)
	{
		Day day;
		readdata(day);
		if(i == 0)
		{
			chartdata[0].date		= day.date;
			chartdata[0].open		= day.open;
			chartdata[0].high		= day.high;
			chartdata[0].low		= day.low;
			chartdata[0].close		= day.close;
			chartdata[0].volume		= day.volume;
			chartdata[0].adjclose	= day.adjclose;
		}

		else
			chartdata.push_back(day);
        }
    return;
}

//Close File
void closefile()
{
    file.close();        //file wird geschlossen
}

int main()
{
	openfile();   
	readfile();
	closefile();
	getchar();
}
</code></pre>
<p>Day.h:</p>
<pre><code>#include &lt;iostream&gt;

//Struct für jeden Tag
struct Day
{
    //Kursdaten
    std::string        date;
    std::string        open;
    std::string        high;
    std::string        low;
    std::string        close;
    std::string        volume;
    std::string        adjclose;
};
</code></pre>
<p>Blöd finde ich, wie ich in die 2. Zeile gelange (nach dem Öffnen der File), aber es funktioniert.<br />
Ist der Code hart dämlich oder akzeptabel?<br />
Es sollte vielleicht erwähnt werden, dass ich mehrere Jahre Historie benötige. Das heißt, es werden ganz schnell mal über 1000 Days, oder gar mehrere 1000e.</p>
<p>Bin auf Kritik gespannt <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/topic/327489/datei-einlesen-und-in-structvektor-schreiben</link><generator>RSS for Node</generator><lastBuildDate>Thu, 09 Jul 2026 15:34:16 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/327489.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 14 Aug 2014 15:08:02 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Datei einlesen und in Structvektor schreiben on Thu, 14 Aug 2014 15:08:02 GMT]]></title><description><![CDATA[<p>Hallo an alle,</p>
<p>ich versuche mich gerade an einem Programm, mit dem ich historische Kursdaten aus .csv Dateien einlese, um damit noch weitere Sachen zu machen (die erstmal unwichtig sind).</p>
<p>Ich wollte einfach mal wissen, was ihr davon haltet, was ich bisher geschrieben habe. Das ist sicherlich keine ideale Lösung, aber hauptsache es funktioniert.</p>
<p>main.cpp:</p>
<pre><code>#include &lt;iostream&gt;
#include &lt;fstream&gt;
#include &lt;string&gt;
#include &lt;vector&gt;
#include &quot;Day.h&quot;

std::ifstream file;    //Die Datei
std::vector&lt;Day&gt; chartdata;

//Open File
void openfile()
{
    file.open(&quot;table.csv&quot;);		//file.csv wird geöffnet
    if(!file.is_open())			//Fehlermeldung   
        std::cerr &lt;&lt; &quot;Fehler beim Öffnen!&quot; &lt;&lt; std::endl;

	size_t    pos;
    std::string search;
    search = &quot;Adj Close&quot;;		//Letzte Spaltenüberschrift, um an den Anfang der 2. Zeile zu gelangen
    std::string line;			//Zum Überspringen der Überschriften
    //Überspringe die Überschriften und setze den Cursor auf das erste Datum
	getline(file, line);        //1. Zeile in line schreiben
    pos = line.find(search);    //suche den String search
    file.seekg(pos + search.length() + 1);			//Setze Cursor hinter die Überschrift

}

std::istream&amp; readdata(Day&amp; day)
{
    getline(file, day.date, ',');
    getline(file, day.open, ',');
    getline(file, day.high, ',');
    getline(file, day.low, ',');
    getline(file, day.close, ',');
    getline(file, day.volume, ',');
    getline(file, day.adjclose, '\n');
    return file;
}

//Read File
void readfile()
{
	chartdata.resize(1);
	for(int i = 0; file.good();i++)
	{
		Day day;
		readdata(day);
		if(i == 0)
		{
			chartdata[0].date		= day.date;
			chartdata[0].open		= day.open;
			chartdata[0].high		= day.high;
			chartdata[0].low		= day.low;
			chartdata[0].close		= day.close;
			chartdata[0].volume		= day.volume;
			chartdata[0].adjclose	= day.adjclose;
		}

		else
			chartdata.push_back(day);
        }
    return;
}

//Close File
void closefile()
{
    file.close();        //file wird geschlossen
}

int main()
{
	openfile();   
	readfile();
	closefile();
	getchar();
}
</code></pre>
<p>Day.h:</p>
<pre><code>#include &lt;iostream&gt;

//Struct für jeden Tag
struct Day
{
    //Kursdaten
    std::string        date;
    std::string        open;
    std::string        high;
    std::string        low;
    std::string        close;
    std::string        volume;
    std::string        adjclose;
};
</code></pre>
<p>Blöd finde ich, wie ich in die 2. Zeile gelange (nach dem Öffnen der File), aber es funktioniert.<br />
Ist der Code hart dämlich oder akzeptabel?<br />
Es sollte vielleicht erwähnt werden, dass ich mehrere Jahre Historie benötige. Das heißt, es werden ganz schnell mal über 1000 Days, oder gar mehrere 1000e.</p>
<p>Bin auf Kritik gespannt <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2413501</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2413501</guid><dc:creator><![CDATA[Mr Joe]]></dc:creator><pubDate>Thu, 14 Aug 2014 15:08:02 GMT</pubDate></item><item><title><![CDATA[Reply to Datei einlesen und in Structvektor schreiben on Thu, 14 Aug 2014 15:45:32 GMT]]></title><description><![CDATA[<p>Fast akzeptabel <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /><br />
- Keine globale Variablen verwenden<br />
- openfile und closefile wegmachen<br />
- readdata durch istream&gt;&gt; Überladung ersetzen<br />
- file.good() durch file&gt;&gt;day; ersetzen<br />
- Wieso ist da so eine Leere in deiner Klasse zwischen string und Bezeichner? Da bekommt man ja schon fast Angst.<br />
- CSV mit Komma? Ich nehm da immer Strichpunkt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2413505</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2413505</guid><dc:creator><![CDATA[out]]></dc:creator><pubDate>Thu, 14 Aug 2014 15:45:32 GMT</pubDate></item><item><title><![CDATA[Reply to Datei einlesen und in Structvektor schreiben on Thu, 14 Aug 2014 18:49:57 GMT]]></title><description><![CDATA[<p>Hallo out,</p>
<p>danke erstmal für deine Antwort <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
<p>Ich habe jetzt openfile und closefile in die main kopiert. Außerdem gibt es keine globalen Variablen mehr.<br />
Das Komma als Trennzeichen wird so geliefert. Mich hat es ehrlich gesagt auch gewundert und hatte da sogar ursprünglich Semikolons stehen <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /><br />
Sogar die große Lücke in der Day.h ist weg <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
<p>Aber das mit den &quot;&gt;&gt;&quot; musst du mir erklären <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f615.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--confused_face"
      title=":confused:"
      alt="😕"
    /> Leider ist Google (oder ich) unfähig danach zu suchen.<br />
&quot;readdata durch istream&gt;&gt; Überladung ersetzen&quot; verstehe ich leider gar nicht.<br />
Und &quot;file.good() durch file&gt;&gt;day; ersetzen&quot;? day wird doch erst in der for-Schleife deklariert und ist an der Stelle noch nicht bekannt. Oder sehe ich das falsch?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2413525</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2413525</guid><dc:creator><![CDATA[Mr Joe]]></dc:creator><pubDate>Thu, 14 Aug 2014 18:49:57 GMT</pubDate></item><item><title><![CDATA[Reply to Datei einlesen und in Structvektor schreiben on Thu, 14 Aug 2014 19:08:20 GMT]]></title><description><![CDATA[<p>Ich will hier nur ein paar Kleinigkeiten anmerken. Was aber nicht heisst dass der Rest OK ist, ich hab nur keine Zeit alle Probleme hier zu beschreiben (und einige andere wurden ja auch schon genannt).</p>
<p>Mr Joe schrieb:</p>
<blockquote>
<pre><code class="language-cpp">//Read File
void readfile()
{
	chartdata.resize(1);
	for(int i = 0; file.good();i++)
	{
		Day day;
		readdata(day);
		if(i == 0)
		{
			chartdata[0].date		= day.date;
			chartdata[0].open		= day.open;
			chartdata[0].high		= day.high;
			chartdata[0].low		= day.low;
			chartdata[0].close		= day.close;
			chartdata[0].volume		= day.volume;
			chartdata[0].adjclose	= day.adjclose;
		}

		else
			chartdata.push_back(day);
        }
    return;
}
</code></pre>
</blockquote>
<p>Wieso nicht einfach</p>
<pre><code class="language-cpp">void readfile()
{
	chartdata.clear();

	while (true)
	{
		Day day;
		readdata(day);
		if (file)
			chartdata.push_back(day);
		else
			break;
	}
}
</code></pre>
<p>Und</p>
<pre><code class="language-cpp">void openfile()
{
    file.open(&quot;table.csv&quot;);     //file.csv wird geöffnet
    if(!file.is_open())         //Fehlermeldung   
        std::cerr &lt;&lt; &quot;Fehler beim Öffnen!&quot; &lt;&lt; std::endl;

    size_t    pos;
    std::string search;
    search = &quot;Adj Close&quot;;       //Letzte Spaltenüberschrift, um an den Anfang der 2. Zeile zu gelangen
    std::string line;           //Zum Überspringen der Überschriften
    //Überspringe die Überschriften und setze den Cursor auf das erste Datum
    getline(file, line);        //1. Zeile in line schreiben
    pos = line.find(search);    //suche den String search
    file.seekg(pos + search.length() + 1);          //Setze Cursor hinter die Überschrift

}
</code></pre>
<p>finde ich anstrengend zu lesen.</p>
<p>Viel besser so:</p>
<pre><code class="language-cpp">void openfile()
{
    file.open(&quot;table.csv&quot;);
    if (!file)
    {
        std::cerr &lt;&lt; &quot;Fehler beim Öffnen!&quot; &lt;&lt; std::endl;
        // TODO: Error handling - just printing a message and then continuing as if nothing had happened is NOT the right thing to do.
    }

    // Read first line

    std::string firstLine;
    getline(file, firstLine);

    // Seek to after the column headers.

    std::string const lastColumnName = &quot;Adj Close&quot;;
    size_t const lastColumnNameStart = firstLine.find(lastColumnName);
    // TODO: Error handling - lastColumnNameStart might be npos (lastColumnName not found).
    file.seekg(lastColumnNameStart + lastColumnName.length() + 1); 
}
</code></pre>
<p>* Kommentare über offensichtliche Dinge entfernt<br />
* Variablen haben ordentliche Namen bekommen<br />
* Kommentare über Dinge entfernt die mit den neuen, besseren Variablennamen nun offensichtlich sind<br />
* Variablen erst dort definieren wo man sie braucht<br />
* Dadurch können wir Variablen oft &quot;const&quot; machen was hilfreich beim Lesen des Codes ist (man sieht sofort &quot;das Ding wird in der Funktion nimmer geändert&quot;)</p>
<p>Sonstinge Dinge:<br />
Die Funktion macht kein korrektes Error-Handling. Was natürlich ganz schlecht ist.<br />
Und ich verstehe den Sinn der ganzen &quot;letzten Spaltennamen suchen&quot; Sache nicht.<br />
Normalerweise sind die Spaltennamen in einem CSV File in der ersten Zeile, und NUR diese in der ersten Zeile.<br />
=&gt; Du kannst alles was nach <code>getline(file, firstLine);</code> kommt weg lassen -- das <code>getline</code> macht ja eh schon genau das was du willst, nämlich die ersten Zeile zu &quot;überlesen&quot;.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2413530</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2413530</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Thu, 14 Aug 2014 19:08:20 GMT</pubDate></item><item><title><![CDATA[Reply to Datei einlesen und in Structvektor schreiben on Fri, 15 Aug 2014 11:45:40 GMT]]></title><description><![CDATA[<p>Hey hustbaer,</p>
<p>danke für die ausführliche Antwort!<br />
Du hast mit der Suche der ersten Zeile völlig recht. Urspünglich dachte ich, die Datei würde aus einer einzigen Zeile bestehen. Als ich gesehen habe, dass das nicht so ist, habe ich meinen Code nicht verbessert, sondern weiter bearbeitet und gar nicht mehr darüber nachgedacht <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f644.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_rolling_eyes"
      title=":rolling_eyes:"
      alt="🙄"
    /></p>
<p>Es ist auch das erste Mal, dass ich einen Vector benutze. Ich wusste gar nicht, dass man mittels</p>
<pre><code>chartdata.push_back(day);
</code></pre>
<p>gleich alle Daten rausholt. Danke <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f44d.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--thumbs_up"
      title=":+1:"
      alt="👍"
    /></p>
<p>Und was du da so unleserlich fandest, damit hattest du völlig recht, fand ich auch.</p>
<p>Bzgl. des Errorhandlings - Wie weit soll ich da gehen? Ich habe nun:</p>
<pre><code>file.open(&quot;table.csv&quot;);
	if (!file)
	{
		std::cerr &lt;&lt; &quot;Fehler beim \x99 \bffnen!\nAnderen Dateinamen eingeben (mit Endung): &quot; &lt;&lt; std::endl;
		// TODO: Error handling - just printing a message and then continuing as if nothing had happened is NOT the right thing to do.
		std::string newfile;
		std::cin &gt;&gt; newfile;
		file.open(newfile);
		if(!file)
		{
			std::cerr &lt;&lt; &quot;Das hat auch nicht geklappt! Vielleicht keine Datei vorhanden?&quot; &lt;&lt; std::endl;
			std::abort();
		}
	}
</code></pre>
<p>Somit wird das Programm nicht aus Versehen weiter ausgeführt. Ich habe überlegt, ob ich noch nach dem Dateinamen fragen soll, bzw. nach einer neuen Datei zum Öffnen. Da ich aber das ganze möglichst einfach haben will, möchte ich möglichst einfach wenn es fertig ist eine .exe ausführen, die mit möglichst wenig Input auskommt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2413595</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2413595</guid><dc:creator><![CDATA[Mr Joe]]></dc:creator><pubDate>Fri, 15 Aug 2014 11:45:40 GMT</pubDate></item></channel></rss>