Datei-basierender Chat
-
Hallo!
Ich bin absoluter Anfänger, das vorweg, und würde liebend gerne C++ lernen ;)... Nun habe ich ein schönes Ziel gefunden und angefangen so zu arbeiten, doch dann frage ich mich nun, nachdem ich schon halb fertig bin, ob mein vorhaben überhaupt realisierbar ist...
Also meine Idee ist folgende: In einer ebenfalls vom Programm erstellbaren Chat-Datei (beliebiger Name.txt) soll gechattet werden können. Spezieller Anwendungszweck: Netzwerk mit gemeinsamen Dateien. Zwei User haben das gleiche Programm, das ist eine wichtige vorraussetzung. Also User 1 öffnet jede Sekunde die Datei und überprüft, ob eine neue Zeile in der Datei hinzugekommen ist (von User 2 geschrieben). Wenn ja, wird diese Zeile ausgegeben. Wenn nein, eben nicht ;)... Geschrieben wird ähnlich: Ein User gibt einen Text ein, der dann in die Datei geschrieben wird.
Dabei habe ich aber einige Fragen oder Probleme, die ich mir vorstellen könnte: Können zwei fopen-Aktionen gleichzeitig auf eine Datei ausgeführt werden? Bzw. wie lange dauert eine solche fopen-Datei lesen-fclose-Aktion, also wie hoch ist die Wahrscheinlichkeit einer überschneidung? Habe ich einen groben Denkfehler gemacht, oder etwas übersehen etc?
Danke schonmal für Rückmeldung

Gruß,
Jonathan
-
Mefisto schrieb:
User 1 öffnet jede Sekunde die Datei und überprüft, ob eine neue Zeile in der Datei hinzugekommen ist (von User 2 geschrieben). Wenn ja, wird diese Zeile ausgegeben. Wenn nein, eben nicht ;)... Geschrieben wird ähnlich: Ein User gibt einen Text ein, der dann in die Datei geschrieben wird.
Warum übergibst du die Zeile nicht gleich an den anderen PC( per sockets )? einfach über threads senden/empfangen->ausgeben
EDIT:
Mefisto schrieb:
Können zwei fopen-Aktionen gleichzeitig auf eine Datei ausgeführt werden?
Zumindest mit std::ifstream sollte das soweit ich weiß möglich sein.
Die ganze Idee ist sowieso uneffektiv, wenn du die selbe Datei auf beiden Rechnern öffnen willst muss sie ja für beide zugänglich sein( samba-share oder sowas ) + du verschwendest unnötig viele ressourcen: usr1: Datei öffnen->in Datei schreiben->datei schließen; usr 2: datei öffnen->prüfen ob neue zeile vorhanden ist->zeile auslesen; Außerdem musst du ja irgendwo die Adresse der Datei, die ja nur auf einem von beiden pcs liegt, herausbekommen - das alles könnte man sich sparen

-
Die beiden "Clients" miteinander zu verbinden wäre für mich viel zu kompliziert, ich weis nichtmal ansatzweise, wie sowas gehen soll. Außerdem geht es ja um einen Chat innerhalb eines Netwerkes... Auf die Idee gekommen bin ich eigentlich während einer langweiligen Softwareschulungsstunde (Excel)... 20 PC's im Netzwerk, einen gemeinsammen Server, auf der dann die Datei liegen würde...
Etwas dauern darf es ja ruhig, also es muss nicht unbedingt schnell sein... Ich hab mir jetzt vorgenommen das Programm soweit erstmal hinzubekommen, ob ich das ganze hinterher noch ändere oder die Socket (??) Funktion noch hinzufüge, kann ich mir ja dann überlegen

Aber ich habe jetzt auch schon mein erstes Problem: Ich will ja, wie das bei einem Chat nunmal so ist, dass auch während des Tippens die Datei aktualisiert wird. Das heißt: Die Datei soll alle 2 Sekunden meinetwegen geöffnet werden, und parallel dazu soll der Benutzer eine Eingabe machen können... Ich habe leider keinen Plan, wie das parallel laufen soll
Wäre sehr, sehr nett, wenn ihr mir da einen Tipp geben könntet 
Gruß,Jonathan
-
So, ich bin fertig, und, egal wie gut, sicher oder stabil der Code und das Programm sind, ich bin mächtig stolz
Hauptsache: Es funktioniert. Überarbeiten kann ich jetzt immernoch. Da ich unter Linux programmiert habe, muss ich das Programm noch in Windows testen, aber da ich schon beim schreiben drauf geachtet habe, dass nichts unkompatibel sein könnte, denke ich, dass es dabei auch nicht zu so vielen Problemen kommen wird.Das Problem mit den parallelen Befehlen habe ich so gelöst: Der User wird dauerhaft mit einer Cin-Eingabe bombadiert. Wenn er enter drückt, wird geguckt, ob ein neuer Eintrag in der Datei ist. Wenn er einen Text eingibt, wird der Text in die Datei geschrieben (angehängt).
Ich würde mich wirklich sehr freuen, wenn ihr zum Code und zum Programm (konstruktive) Tipps geben könntet... Vielen Dank schonmal

#include <iostream> #include <string> #include <fstream> #include <vector> #include <ctime> using namespace std; void wait() { cin.clear(); cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); cin.ignore(); } int main() { string choice = ""; while(choice!="1" && choice!="2" && choice!="3") { cout << "Welcome to FBC, File-based Chat. This \n"; cout << "Chat worksvery simple; you can chat with\n"; cout << "a partner over afile somewhere in your\n"; cout << "or his system over a network-connection.\n"; cout << "You don't need an internet-connection to\n"; cout << "chat over the home network. Please re-\n"; cout << "member: Your chat can be viewed, de-\n"; cout << "or changed over the file that contains the\n"; cout << "chat.\n\n"; cout << "Please choose whether you want to create\n"; cout << "a new file-chat or you wan't to join an\n"; cout << "existing file-chat!\n\n"; cout << "1. Create new File-Chat\n"; cout << "2. Join existing File-Chat\n"; cout << "3. Exit Program\n"; cout << "4. Show Help for this step.\n\n"; cout << "Please enter your choice: "; getline (cin, choice); if(choice == "4") { cout << "\n\n-----> HELP for Step 1\n\n"; cout << "This program allowes you to chat over a\n"; cout << "file that lies somewhere on your or your\n"; cout << "chat-partners system (or in the internet)\n"; cout << "One partner has to create the chat-file,\n"; cout << "before the other can join the chat. You\n"; cout << "must choose one chat leader (that creates\n"; cout << "the chat-file. If you want to create this\n"; cout << "chat-file (create a new kind of \"chatroom\"\n"; cout << "you must choose the option 1 in the menu.\n"; cout << "if you partner creates the file, you just\n"; cout << "need to join the chat. Choose option 2 to\n"; cout << "do this. Press any key to continue!"; wait(); } if(choice=="1") { string chatfilename; string chatdirectory; string leadername; string leaderpassword; string accesspassword; cout << "Chat-File-Name: "; while(chatfilename == "") { getline(cin,chatfilename); } chatfilename = chatfilename+".txt"; cout << "Chat-Directory: "; getline(cin,chatdirectory); while(leadername.length() <= 4 || leadername.length() >= 20) { cout << "Enter your name: "; getline(cin,leadername); } while(leaderpassword.length() <= 6 || leaderpassword.length() >= 20) { cout << "Enter your password: "; getline(cin,leaderpassword); } while(accesspassword.length() <= 6 || accesspassword.length() >= 20) { cout << "Enter access-password: "; getline(cin,accesspassword); } int success; string finalpath = chatdirectory+chatfilename; string finalleader = "Leadername: "+leadername+"\nLeaderpass: "+leaderpassword+"\nAccesspass: "+accesspassword; char buffer1[finalpath.length()-1]; char buffer2[finalleader.length()-1]; strcpy(buffer1,finalpath.c_str()); strcpy(buffer2,finalleader.c_str()); FILE* fp; fp = fopen(buffer1,"w"); if (fprintf(fp, buffer2)) { success = 1; } else { success = 0; } fclose(fp); if(success==1) { cout << "\n\nYour new chat had been created! Don't\n"; cout << "forget your password! You can move or copy\n"; cout << "the file as often as you want, all chat-di-\n"; cout << "aloges will be saved within here. Press en-\n"; cout << "ter to get back to the main-menu.\n"; } else { cout << "\n\nAn error occured during writing the\n"; cout << "file. Directory must end with a slah (nor-\n"; cout << "mal). Press enter to get back to the main-\n"; cout << "menu.\n"; } wait(); } if(choice == "3") { return 1; } if(choice == "2") { string chatfilelocation; string chatpassword; string chatusername; vector<string> rows; string row; int open = 0; int pass = 0; int counter = 0; while(open == 0) { cout << "Chat-File-Location: "; getline(cin,chatfilelocation); char buffer1[chatfilelocation.length()-1]; strcpy(buffer1,chatfilelocation.c_str()); ifstream file(buffer1); if(file!=NULL) { open = 1; while(getline(file,row)) { if(counter < 3) { row.replace(0,12,""); } rows.push_back(row); counter++; } } } while(chatpassword.length() <= 6 || chatpassword.length() >= 20 || pass == 0) { cout << "Chat-Password: "; getline(cin,chatpassword); if(chatpassword==rows[2]) { pass = 1; } } while(chatusername.length() <= 4 || chatusername.length() >= 20) { cout << "Enter your name: "; getline(cin,chatusername); } char buffer1[chatfilelocation.length()-1]; strcpy(buffer1,chatfilelocation.c_str()); ifstream file(buffer1); cout << "You logged in this file-chat successful-\n"; cout << "ly! Before you start chatting, here a few\n"; cout << "informations about that file-chat:\n"; cout << "Leader: " << rows[0] << endl; cout << "Lines already written: " << counter-3 << "\n\n"; cout << "Check for new answers: Press enter\n"; cout << "Write a text to chat-file: Just enter!\n"; int endrequest=0; int countertemp = 0; int callrenew = 0; string temp; while(endrequest!=1) { if (callrenew != 1) {getline(cin,temp); } if(temp == "" || callrenew == 1) { ifstream file(buffer1); while(getline(file,row)) { countertemp++; if(countertemp>counter) { rows.push_back(row); } } if(countertemp>counter) { for (int i=0; i<countertemp-counter;i++) { cout << ">>> " << rows[counter+i] << endl; } counter = countertemp; } countertemp = 0; callrenew = 0; } if(temp!="") { time_t rawtime; struct tm * timeinfo; time ( &rawtime ); timeinfo = localtime ( &rawtime ); ofstream file(buffer1, ios::app); file << "\n" << asctime (timeinfo) << chatusername << ": " <<temp; file.close(); temp = ""; callrenew = 1; } } } choice = ""; } return 0; }
-
Also ich hab ehrlichgesagt keine Lust und Zeit mir den code anzuschaun
später vielleicht.Aber ich habe jetzt auch schon mein erstes Problem: Ich will ja, wie das bei einem Chat nunmal so ist, dass auch während des Tippens die Datei aktualisiert wird. Das heißt: Die Datei soll alle 2 Sekunden meinetwegen geöffnet werden, und parallel dazu soll der Benutzer eine Eingabe machen können... Ich habe leider keinen Plan, wie das parallel laufen soll :/ Wäre sehr, sehr nett, wenn ihr mir da einen Tipp geben könntet :)benutz doch fstreams, die
erlauben lesen+schreiben auf einmal.Generell zum code: benutze Klassen und Funktionen. Dein code wirkt so nämlich total unübersichtlich. Für größere Projekte ist es außerdem überlebenswichtig eben genanntes zu benutzen, wenn man 100.000 Zeilen in die main-funktion quetschen würde, würde kein Mensch mehr verstehen, was du da programmiert hast.
EDIT:
beim überfliegen aufgefallen:
- keine kommentare benutztwhile(chatfilename == "") { getline(cin,chatfilename); }unsinn.
if (fprintf(fp, buffer2)) { success = 1; } else { success = 0; }warum schreibst du nicht gleich die anweisungen in diese Blöcke anstatt nacher mit if(success==..) abzufragen?
char buffer1[chatfilelocation.length()-1]; strcpy(buffer1,chatfilelocation.c_str()); ifstream file(buffer1);machs so:
ifstream( chatfilelocation.c_str() )mfg
Double *T
-
Danke schonmal für die guten Tipps, die werde ich morgen gleich umsetzen!

Mir erschien es mit Funktionen immer genauso unübersichtlich, aber eben beim lesen ist mir ein Gedankenblitz gekommen: Ich kann die Funktionen ja in eine externe Datei schreiben und die einfach einbinden... Wow :D...
Liebe Grüße,
Jonathan
-
Mir erschien es mit Funktionen immer genauso unübersichtlich, aber eben beim lesen ist mir ein Gedankenblitz gekommen: Ich kann die Funktionen ja in eine externe Datei schreiben und die einfach einbinden
Wow.. Das muss gefeiert werden..

btw:
Da sollte wirklich ein wenig mehr OOP rein.
-
Mir erschien es mit Funktionen immer genauso unübersichtlich, aber eben beim lesen ist mir ein Gedankenblitz gekommen: Ich kann die Funktionen ja in eine externe Datei schreiben und die einfach einbinden... Wow :D...
Funktioonen/Klassen haben übrigends außer übersichtlichkeit viele andere Vorteile, wie codewiederverwertung, Librarys, zum Beispiel, auch selbstgeschriebene, bestehen immer aus Klassen und/oder Funktionen. Durch Funktionen/Klassen entsteht auch eine gewisse abstraktion, man schreibt also zum beispiel nur "Sinus( 123 )" ohne zu wissen/wissen zu müssen, was da eigentlich genau vor sich geht, anstatt mehrere zeilen code jedes mal aufs neue in die main funktion zu schreiben.
Gewöhn dir das also gleich an
mfg
Double *T