reinterpret_cast<char*>(&string) oder string.c_str()



  • std::string und std::ios::binary - was willst du denn eigentlich machen?



  • Okay, danke. 😉

    Ich habe das nur verwendet, weil, wenn es char* akzeptiert, macht es eigentlich Sinn, wenn auch ein String funktioniert.

    Natürlich wissen die Macher und die Allermeisten hier besser darüber Bescheid. Sonst würde ich nicht fragen. 😉
    Weshalb ist aber denn dann bei write beides richtig (oder besser: ausführbar)? Ist eines davon dem anderen vorzuziehen (bzw. wurde Nr. 2 ja schon als schlecht abgestempelt; dann lieber Nr. 1 oder &name[0])?

    Edit: das binary ist da eigentlich mehr oder weniger nur zum Ausprobieren. Hat weder einen Sinn noch einen Zweck.

    Das hier wäre aber theorethisch der Code (nichts sinnvolles, nur testen 😃 ):

    #include <iostream>
    #include <iomanip>
    #include <fstream>
    #include <string>
    #include <limits>
    
    void lastfileopenrequest(std::string &dateiname, std::string &newdateiname, int &wdh);
    
    int main()
    {
    	std::string dateiname, newdateiname;
    	std::string content, existcontent, partexistcontent;
    	int wdh = 3;
    
    	int format = 120;   //Standard-Wert: 120
    
    	lastfileopenrequest(dateiname, newdateiname, wdh);
    
    	std::fstream editdatei;
    
    	if (wdh == 1)
    	{
    		editdatei.open(newdateiname, std::ios::in);
    		if (!editdatei)
    		{
    			std::cout << "\n\n\nFile not found.\n\nPress 'Enter' to exit.\n\n";
    			std::cin.sync();
    			std::cin.get();
    			editdatei.close();
    			return 0;
    		}
    		else
    		{
    			std::cout << std::endl << std::endl << '[' << newdateiname << ']' << std::endl << std::endl << std::endl
    				<< std::setfill('-') << std::setw(format) << " ";
    
    			while (std::getline(editdatei, partexistcontent))
    			{
    
    				int a = partexistcontent.length(), b = partexistcontent.length(), anzahl = format - 1, timer = 0; 
    				unsigned int stelle = 0;
    				std::string erased;
    
    				do
    				{
    					if (b > format)
    					{
    
    						if (stelle == 0)
    						{
    							erased = partexistcontent.substr(stelle, anzahl);		// anzahl + 1
    						}
    						else
    						{
    							erased = partexistcontent.substr(stelle - timer, anzahl);		// anzahl + 1
    						}
    
    						if (erased.rfind(' ', erased.length()) > 0 && erased.rfind(' ', erased.length()) < erased.length())
    						{
    							erased = erased.erase(erased.rfind(' ', erased.length()) + 1, erased.length());
    						}
    
    						existcontent += erased;
    						existcontent += '\n';
    					}
    					else if (b < format)
    					{
    						if (stelle < 1)
    						{
    							erased = partexistcontent.substr(stelle, b);
    						}
    						else
    						{
    							erased = partexistcontent.substr(stelle - timer, b);
    						}
    
    						existcontent += erased;
    					}
    					/*else
    					{
    						std::cout << "\n\nAn Issue occured!\n\n";
    					}*/
    
    					stelle = (stelle + (format - (format - erased.length())) + 1);
    					b = b - erased.length();
    					a = a - format;
    					timer++;
    
    				} while (b > -(format - 1) && stelle <= partexistcontent.length());
    
    				existcontent += '\n';
    				if (stelle != 0 || anzahl != format - 1)
    				{
    					existcontent += '\n';
    				}
    
    			}
    				std::cout << std::endl << existcontent << std::endl
    					<< std::setfill('-') << std::setw(format) << " ";
    
    			editdatei.close();
    
    			int wdh2 = 3;
    			do
    			{
    
    				std::string choo;
    				std::cout << "\n\nOverwrite existing content?\n\n\t1. Yes\n\n\t2. No\n\n";
    
    				std::cin >> choo;
    
    				if (choo == "1" || choo == "yes" || choo == "Yes" || choo == "y" || choo == "Y")
    				{
    					editdatei.open(newdateiname, std::ios::out | std::ios::trunc);
    					if (!editdatei)
    					{
    						std::cout << "\n\n\nFile not found.\n\nPress 'Enter' to exit.\n\n\n";
    						std::cin.sync();
    						std::cin.get();
    						editdatei.close();
    						return 0;
    					}
    					wdh2 = 1;
    				}
    				else if (choo == "2" || choo == "no" || choo == "No" || choo == "n" || choo == "N")
    				{
    					editdatei.open(newdateiname, std::ios::out | std::ios::app);
    					if (!editdatei)
    					{
    						std::cout << "\n\n\nFile not found.\n\nPress 'Enter' to exit.\n\n\n";
    						std::cin.sync();
    						std::cin.get();
    						editdatei.close();
    						return 0;
    					}
    					wdh2 = 2;
    				}
    				else
    				{
    					std::cout << "\n\n\nIncorrect Input. \n\nPress 'Enter' to retry.\n\n";
    					std::cin.sync();
    					std::cin.get();
    					wdh2 = 0;
    				}
    			} while (wdh2 == 0);
    
    			std::cout << "\n\nUse '$' to mark the end. Enter the data to be stored in " << newdateiname << ':' << std::endl << std::endl;
    			std::getline(std::cin, content, '$');
    			std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    
    			editdatei << content << std::endl;
    			editdatei.close();
    
    		}
    	}
    	else if (wdh == 2)
    	{
    		editdatei.open(dateiname, std::ios::in);
    		if (!editdatei)
    		{
    			std::cout << "\n\n\nFile not found.\n\nPress 'Enter' to exit.\n\n";
    			std::cin.sync();
    			std::cin.get();
    			editdatei.close();
    			return 0;
    		}
    		else
    		{
    			std::cout << std::endl << std::endl << '[' << dateiname << ']' << std::endl << std::endl << std::endl
    				<< std::setfill('-') << std::setw(format) << " ";
    
    			while (std::getline(editdatei, partexistcontent))
    			{
    
    				int a = partexistcontent.length(), b = partexistcontent.length(), anzahl = format - 1, timer = 0;
    				unsigned int stelle = 0;	
    				std::string erased;
    
    				do
    				{
    					if (b > format)
    					{
    
    						if (stelle == 0)
    						{
    							erased = partexistcontent.substr(stelle, anzahl);		// anzahl + 1
    						}
    						else
    						{
    							erased = partexistcontent.substr(stelle - timer, anzahl);		// anzahl + 1
    						}
    
    						if (erased.rfind(' ', erased.length()) > 0 && erased.rfind(' ', erased.length()) < erased.length())
    						{
    							erased = erased.erase(erased.rfind(' ', erased.length()) + 1, erased.length());
    						}
    
    						existcontent += erased;
    						existcontent += '\n';
    					}
    					else if (b < format)
    					{
    						if (stelle < 1)
    						{
    							erased = partexistcontent.substr(stelle, b);
    						}
    						else
    						{
    							erased = partexistcontent.substr(stelle - timer, b);
    						}
    
    						existcontent += erased;
    					}
    					else
    					{
    						std::cout << "\n\nAn Issue occured!\n\n";
    					}
    
    					stelle = (stelle + (format - (format - erased.length())) + 1);
    					b = b - erased.length();
    					a = a - format;
    					timer++;
    
    				} while (b > -(format - 1) && stelle <= partexistcontent.length());
    
    				existcontent += '\n';
    				if (stelle != 0 || anzahl != format - 1)
    				{
    					existcontent += '\n';
    				}
    
    			}
    
    			std::cout << std::endl << existcontent << std::endl
    				<< std::setfill('-') << std::setw(format) << " ";
    		}
    
    		editdatei.close();
    		if (existcontent.length() >= 1)
    		{
    			int wdh2 = 3;
    			do
    			{
    
    				std::string choo;
    				std::cout << "\n\nOverwrite existing file?\n\n\t1. Yes\n\n\t2. No\n\n";
    
    				std::cin >> choo;
    
    				if (choo == "1" || choo == "yes" || choo == "Yes" || choo == "y" || choo == "Y")
    				{
    					editdatei.open(dateiname, std::ios::out | std::ios::trunc);
    					if (!editdatei)
    					{
    						std::cout << "\n\n\nFile not found.\n\nPress 'Enter' to exit.\n\n\n";
    						std::cin.sync();
    						std::cin.get();
    						exit(0);
    					}
    
    					std::cout << "\n\nUse '$' to mark the end. Enter the data to be stored in " << dateiname << ':' << std::endl << std::endl;
    					std::getline(std::cin, content, '$');
    					std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    
    					editdatei << content << std::endl;
    					editdatei.close();
    
    					wdh2 = 1;
    				}
    				else if (choo == "2" || choo == "no" || choo == "No" || choo == "n" || choo == "N")
    				{
    					editdatei.open(dateiname, std::ios::out | std::ios::app);
    					if (!editdatei)
    					{
    						std::cout << "\n\n\nFile not found.\n\nPress 'Enter' to exit.\n\n\n";
    						std::cin.sync();
    						std::cin.get();
    						exit(0);
    					}
    
    					std::cout << "\n\nUse '$' to mark the end. Enter the data to be stored in " << dateiname << ':' << std::endl << std::endl;
    					std::getline(std::cin, content, '$');
    					std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    
    					editdatei << content << std::endl;
    					editdatei.close();
    
    					wdh2 = 2;
    				}
    				else
    				{
    					std::cout << "\n\n\nIncorrect Input. \n\nPress 'Enter' to retry.\n\n";
    					std::cin.sync();
    					std::cin.get();
    					wdh2 = 0;
    				}
    			} while (wdh2 == 0);
    
    		}
    		else
    		{
    			editdatei.open(dateiname, std::ios::out);
    			std::cout << "\n\nUse '$' to mark the end. Enter the content of " << dateiname << ':' << std::endl << std::endl;
    			std::getline(std::cin, content, '$');
    			std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    
    			editdatei << content << std::endl;
    			editdatei.close();
    		}
    	}
    
    	editdatei.close();
    
    	return 0;
    }
    
    void lastfileopenrequest(std::string &dateiname, std::string &newdateiname, int &wdh)
    {
    std::ifstream lastfilein;
    
    do
    {
    	std::cout << "Open last used file?\n\n\t1. Yes\n\n\t2. No\n\n";
    	std::getline(std::cin, dateiname);
    	if (dateiname == "1" || dateiname == "yes" || dateiname == "Yes" || dateiname == "y" || dateiname == "Y")
    	{
    	lastfilein.open("lastfile.bn", std::ios::binary | std::ios::in);
    	if (!lastfilein)
    	{
    		std::cout << "\n\nlastfile.bn not found!";
    	}
    
    	//lastfilein >> newdateiname;
    	std::getline(lastfilein, newdateiname);
    	/*lastfilein.seekg(0, std::ios::end);
    	int newdateinamekength = lastfilein.tellg();
    	lastfilein.seekg(0, std::ios::beg);
    	lastfilein.read(const_cast<char*>(newdateiname.data()), newdateinamekength);
    	//lastfilein.read(reinterpret_cast<char*>(&newdateiname), newdateinamekength);*/
    
    	//std::cout << std::endl << std::endl << '[' << newdateiname << ']';// << std::endl << newdateinamekength;
    	std::cout << newdateiname << '!';
    	lastfilein.close();
    
    	wdh = 1;
    	}
    	else if (dateiname == "2" || dateiname == "no" || dateiname == "No" || dateiname == "n" || dateiname == "N")
    	{
    		int wdh3 = 3;
    
    		do
    		{
    
    			std::string choo2;
    
    			std::cout << "\n\nCreate a new file?\n\n\t1. Yes\n\n\t2. No\n\n";
    
    			std::cin >> choo2;
    			std::cin.sync();
    
    			if (choo2 == "1" || choo2 == "yes" || choo2 == "Yes" || choo2 == "y" || choo2 == "Y")
    			{
    				wdh3 = 1;
    			}
    			else if (choo2 == "2" || choo2 == "no" || choo2 == "No" || choo2 == "n" || choo2 == "N")
    			{
    				std::ifstream oldfileoutcheck;
    				wdh3 = 2;
    			}
    			else
    			{
    				std::cout << "\n\n\nIncorrect Input. \n\nPress 'Enter' to retry.\n\n";
    				std::cin.sync();
    				std::cin.get();
    				wdh3 = 0;
    			}
    		} while (wdh3 == 0);
    
    		int wdh4 = 3;
    
    			std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    		do
    		{
    			std::cout << "\n\nPlease enter the filename: ";
    			std::getline(std::cin, dateiname, '\n');
    
    			if (wdh3 == 1)
    			{
    				std::ifstream newfileoutcheck(dateiname);
    				if (newfileoutcheck)
    				{
    					std::cout << std::endl << std::endl << dateiname << " already exists!\n\nPress 'Enter' to retry.\n\n\n";
    					std::cin.sync();
    					std::cin.get();
    					wdh4 = 0;
    				}
    				else
    				{
    					std::ofstream lastfileout("lastfile.bn", std::ios::binary | std::ios::out);
    					if (!lastfileout)
    					{
    						std::cout << "\n\nAn Issue occurred while writing in \"lastfile.bn\"!\n\nPress 'Enter' to continue without saving the session.";
    						std::cin.sync();
    						std::cin.get();
    					}
    
    					//lastfileout.write(reinterpret_cast<char*>(&dateiname), dateiname.size());
    					//lastfileout.write(dateiname.c_str(), dateiname.size());
    					lastfileout << dateiname;
    
    					lastfileout.close();
    
    					std::ofstream createfile(dateiname);
    					createfile.close();
    					wdh4 = 1;
    				}
    				newfileoutcheck.close();
    			}
    			else if (wdh3 == 2)
    			{
    				std::ifstream oldfileoutcheck(dateiname);
    				if (!oldfileoutcheck)
    				{
    					std::cout << std::endl << std::endl << dateiname << " does not exist!\n\nPress 'Enter' to retry\n\n\n";
    					std::cin.sync();
    					std::cin.get();
    					wdh4 = 0;
    				}
    				else
    				{
    					std::ofstream lastfileout("lastfile.bn", std::ios::binary | std::ios::out);
    					if (!lastfileout)
    					{
    						std::cout << "\n\nAn Issue occurred while writing in \"lastfile.bn\"!\n\nPress 'Enter' to continue without saving the session.";
    						std::cin.sync();
    						std::cin.get();
    					}
    
    					//lastfileout.write(reinterpret_cast<char*>(&dateiname), dateiname.size());
    					//lastfileout.write(dateiname.c_str(), dateiname.size());
    					lastfileout << dateiname;
    
    					lastfileout.close();
    					wdh4 = 2;
    				}
    				oldfileoutcheck.close();
    			}
    
    		} while (wdh4 == 0);
    
    		wdh = 2;
    	}
    	else
    	{
    		std::cout << "\n\n\nIncorrect Input. \n\nPress 'Enter' to retry.\n\n";
    		std::cin.sync();
    		std::cin.get();
    		wdh = 0;
    	}	
    
    } while (wdh == 0);
    
    }
    


  • Skylac06 schrieb:

    (nichts sinnvolles, nur testen 😃 ):

    Teste mal was sinnvolles: Funktionen!



  • Das hängt aber ja alles mehr oder weniger zusammen. Würde ich noch etwas hinzufügen, würde ich einfach die gesamte Main-Funktion in eine andere Funktion packen und eben eine deutlich leerere Main-Funktion haben.
    Wäre das dann besser?
    Und wirklich übersichtlicher wird es ja auch nicht, wenn man ständig zwischen den Funktionen hin- und herhüpfen muss. Wiederholt wird ja eigentlich nicht so viel mehrmals.



  • Das hängt aber ja alles mehr oder weniger zusammen.

    das ist bei jeder Software so 🙂 trotzdem schaffen es so einige verständlicheren Quelltext mit Funktionen aus so einer Aufgabe zu machen

    z.B. Eingabe von Verarbeitung trennen wäre ja schon mal was - oder?

    bei dir ist das leider ein einziger Datei-oeffnen-lesen-formatieren-substrings-if-if-if-while-if-if-Datei-schliessen-Schlonz



  • Also sorry nochmal, ich dachte fälschlicherweise wirklich dass .data() nen char* (ohne const ) zurückgibt. Die Merkleistung sinkt wohl auch mit dem Alter... hmpf.
    Der const_cast ist natürlich Unfug.

    Hab jetzt selbst nochmal gegoogelt, und ja, &s[0] sollte garantierterweise (ab C++11) funktionieren - und funktioniert auch mit üblichen C++98 Standard Library Implementierungen.
    Warum es keine Memberfunktion gibt die &s[0] als schreibbaren Zeiger zurückgibt verstehe ich allerdings nicht ganz. Oversight kommt mMn. nicht in Frage, dazu wurde in C++11 zu viel explizit erlaubt was man mit &s[0] machen möchte.

    ps: Vielleicht weil der naheliegende Funktionsname (data) schon vergeben war 😃


  • Mod

    Ich vermute, die Intention ist, dass string nicht für solche Hacks gedacht ist, sondern wirklich nur für high-level Zeichenkettenlogik. Wenn man direkt in Arrays rumschreiben möchte, dann ist vector angesagt.



  • http://en.cppreference.com/w/cpp/string/basic_string/data sagt

    const CharT* data() const; (1) 	
          CharT* data();       (2) (since C++17)
    


  • Danke euch allen für die zahlreichen Anworten. 🙂

    Ich habe den Code von oben noch einmal auf Funktionen aufgeteilt:

    #include <iostream>
    #include <iomanip>
    #include <fstream>
    #include <string>
    #include <limits>
    
    void lastfileopenrequest(std::string &dateiname, std::string &newdateiname, int &wdh);
    void formatting(std::string partexistcontent, int format, std::string &existcontent);
    void openeditdatei(std::fstream &editdatei, std::string dateiname, std::string partexistcontent, std::string &existcontent, int format);
    void oneoverwrite(std::fstream &editdatei, std::string dateiname);
    void twooverwrite(std::fstream &editdatei, std::string dateiname);
    void threeoverwrite(std::fstream &editdatei, std::string dateiname, std::string existcontent);
    void fouroverwrite(std::fstream &editdatei, std::string dateiname, std::string existcontent);
    
    int main()
    {
    	std::string dateiname, newdateiname;
    	std::string existcontent, partexistcontent;
    	int wdh = 3;
    
    	int format = 120;														  //Standard-Wert: 120
    
    	lastfileopenrequest(dateiname, newdateiname, wdh);
    
    	std::fstream editdatei;
    
    	if (wdh == 1)
    	{
    		openeditdatei(editdatei, newdateiname, partexistcontent, existcontent, format);
    
    		fouroverwrite(editdatei, newdateiname, existcontent);
    
    	}
    	else if (wdh == 2)
    	{
    		openeditdatei(editdatei, dateiname, partexistcontent, existcontent, format);
    
    		threeoverwrite(editdatei, dateiname, existcontent);
    	}
    
    	return 0;
    }
    
    void lastfileopenrequest(std::string &dateiname, std::string &newdateiname, int &wdh)
    {
        ...
    }
    
    void formatting(std::string partexistcontent, int format, std::string &existcontent)
    {
        ...
    }
    void openeditdatei(std::fstream &editdatei, std::string dateiname, std::string partexistcontent, std::string &existcontent, int format)
    {
        ...
    }
    
    void oneoverwrite(std::fstream &editdatei, std::string dateiname)
    {
        ...
    }
    
    void twooverwrite(std::fstream &editdatei, std::string dateiname)
    {
        ...
    }
    
    void threeoverwrite(std::fstream &editdatei, std::string dateiname, std::string existcontent)
    {
        ...
    }
    
    void fouroverwrite(std::fstream &editdatei, std::string dateiname, std::string existcontent)
    {
        ...
    }
    

    Den Funktionscode habe ich der Übersichtlichkeit halber weggelassen.
    Ist das so besser oder sind das jetzt zu viele Funktionen?
    Und sollte ich ab jetzt lieber jeden Code so schreiben? Weil das ja eigentlich eher etwas mehr Arbeit ist... 😃

    Edit: Wobei die Anzahl der Schleifen und Bedingungen gleich geblieben ist...
    Aber es gibt auch keine Möglichkeit, welche wegzulassen. Das Einzige, was mir einfallen würde, wäre, die while-Schleifen durch goto zu ersetzen. Aber das ist ja wohl noch schlimmer.
    Also so lassen? 😕



  • Das schlimmste an deinem Code ist, dass man anhand der Funktionsnamen nicht erkennen kann, was überhaupt passieren soll.

    Daher helfen insbesondere Funktionsnamen wie "oneoverwrite" nicht!

    Und dann ist da noch die Variable "wdh". Was tut die? Warum sind das alles "void"-Funktionen, warum gibt keine irgendwas sinnvolles zurück?

    Generell: wenn eine Funktion mehr als 50 Zeilen Code hat, darf man schon einmal nachfragen, warum die Funktion so lang ist. Nun kann man sich über die 50 streiten und ggf. 70 sagen, während anderen 50 schon zu viel ist*. Aber 300 Codezeilen, was du im ersten Beispiel hattest, ist viel viel zu lang.

    [*]
    das hängt natürlich auch davon ab, was in der Funktion drin ist. Wenn das 50 Zeilen mit "cout << ..." sind oder irgendwelche anderen trivialen Dinge, dann sehe ich kein Problem mit längeren Funktionen. Wenn du aber irgendwelche Kontrollstrukturen dabei hast, dann lieber kurz als lang.



  • Bei Funktionsnamen habe ich immer ein Problem. Da finde ich nur selten etwas passendes...

    oneoverwrite() ist die Abfrage, ob der Inhalt überschrieben werden soll und die Eingabe.
    twooverwrite() macht das gleiche, nur auf eine andere Weise.
    threeoverwrite() fasst openeditdatei() und Oneoverwrite() zusammen und überprüft, ob in der Datei überhaupt etwas drinnen steht.
    Fouroverwrite() ist das gleiche wie threeoverwrite() nur mit twooverwrite().

    Als wdh bezeichne ich immer die Variable, die in while-Schleifen die Durchläufe regelt, meistens im Zusammenhang mit Eingabefehlern. Hier habe ich sie zusätzlich dazu benutzt um von der Auswahl in lastfileopenrequest() abhängig die nächsten Anweisungen zu bestimmen.

    Es sind alles void-Funktionen, weil ich den Code eigentlich am Stück geschrieben habe und nur auf Funktionen aufgeteilt habe. Ich habe hier fast alles mit Referenzen gemacht.
    Natürlich habe ich return 0 durch exit(0) ersetzt. Hier wäre eventuell noch die Frage, ob das wirklich richtig so ist...

    Aber dein Richtwert von 50-70 Zeilen klingt gut, danke. Ich werde mich versuchen daran zu halten.

    Noch eine allerletzte Frage: soll ich von Anfang an mit Funktionen schreiben oder dann erst den fertigen Code wie hier zerlegen?



  • Skylac06 schrieb:

    Bei Funktionsnamen habe ich immer ein Problem. Da finde ich nur selten etwas passendes...

    Passende Namen sind wichitg für die Wartbarkeit. Versuch mal in 2 Monaten zu verstehen, was du da gemacht hast 😉

    Skylac06 schrieb:

    Noch eine allerletzte Frage: soll ich von Anfang an mit Funktionen schreiben oder dann erst den fertigen Code wie hier zerlegen?

    Von Anfang an Objektorientiert!



  • Ich werde es versuchen. 🙂
    Danke! 😉


Anmelden zum Antworten