stand 12.12.03 zum allg. Verständnis v. Zeigern & Adressen int x=5, y=0; int *zeiger; zeiger = &x; y = *zeiger; // nun ist y=5; oder: char *c[] = {"ENTER", "NEW", "POINT", "FIRST"}; // Im Speicher steht ENTER, NEW, POINT, FIRST char **cp[] = {c+3, c+2, c+1, c}; // cp referenziert FIRST,POINT,NEW,ENTER char ***cpp=cp; // cpp steht auf FIRST int main (void) { printf("%s",** ++cpp); // cpp erhöhen auf POINT, ausgeben : POINT printf("%s",*--* ++cpp+3); // cpp erhöhen auf NEW, referenz von NEW auf ENTER reduzieren, ausgabe ab dem 3. Zeichen von ENTER: ER printf("%s",*cpp[-2]+3); // über cpp auf cp zugreifen, ausgabe ab dem 3. Zeichen von FIRST : ST printf("%s\n",cpp[-1][-1]+1); // über cpp auf cp auf c zugreifen, ausgabe ab dem 1. Zeichen von NEW: EW } // Ergebnis: POINTERSTEW ---Variabelenübergabe bei Prozeduren main() { int i=5, j, re; char text[10]; typedef char string20[20]; string20 liste[X]; strcpy(liste[list_zeiger],"einheit"); re = sub(i, &j, text, liste); } sub (int a, int* b_adr, char* tx, string20* s_liste) { *b_adr = 7; // weist j in main() 7 zu printf("Text aus main %s\n", tx); if(!strcmp(liste[X],"einheit")).... strcpy(liste[X],"Text ");... return a+2; // gibt an main() 7 zurück (5+2) } ---SCHLEIFEN & BEDINGUNGEN for (Var-DEF; Abbruchbedingung; Var-Mod) { // oder while (Abbruchbedingung) { // wenn Bed = 1 -> Endlos oder do { } while (Abbruchbed.); break; // Schleife wird abgebrochen continue; // sprtingt zum Ende und prüft Bedingung neu boolsche Abbruchbedingung möglich z.B.: ((a==x || b!=y) && c<7) ich kann's mir einfach nicht merken: a = (b eigener_typname a; oder eigener_typname a[X]; //möglich ---STRINGOPERATIONEN char text[10] = {"Hallo\0"}; int i=7; printf("format",a , b,...); // format: %d=dezimal, %x=hex %c=char, %s=string, %f=float // %4d länge 4, %ld long, (auch %8ld mögl) %20s string länge 20 BSP printf("dezi:%d char:%c str:%s\n", i, text[2], text); // -> dezi:7 char:l str:Hallo strcpy(text, "Hi"); // mit \0 wird abgeschlossen ...oder sprintf(text, "Hi"); strcat(text, " Du"); // Du wird an Hi angehängt re=strcmp(text, "Hi Du"); // gibt anz. der unterschiedlichen Zeichen aus, wenn alles gleich -> re=0 re=strlen(text); // gibt stringlänge aus ---DATEIOPERATIONEN# char bin_bild[1000]; int real_ength; FILE *sichern; sichern=fopen ("C:\\test.txt","wb"); //write binary (a=anhängen) fwrite(&real_length,(size_t)(sizeof(int)),(size_t)1,sichern); //eine einzelne var z.B. die Länge der folgenden fwrite(bin_bild,(size_t)(real_length),(size_t)1,sichern); // undefinierten datenlänge eines Pointers for(i=0; i<=anz_einheiten; i++) { fwrite(&einheit[i],(size_t)(sizeof(einheit[0])),(size_t)1,sichern); // ein array von Strukturen } fclose(sichern); // zu guter schluß das File wieder schließen // hinweis text ist auch einfach mit z.B. fprintf(sichern, "Nase %d %s\n",5,"Hase"); // will man das gespeicherte wieder lesen...in gleicher Reihenfolge FILE *sichern; sichern=fopen ("C:\\test.txt","rb"); //read binary fread(&i,(size_t)(sizeof(int)),(size_t)1,sichern); //eine einzelne var for(i=0; i<=anz_einheiten; i++) { fread(&einheit[i],(size_t)(sizeof(einheit[0])),(size_t)1,sichern); // ein array von Strukturen } fclose(sichern); // zu guter schluß das File wieder schließen ---PRÄPROZESSORANWEISUNG #define EH_MAX 10000 // EH_MAX wird überall dutch 1000 ersetzt #define STR Hallo // wenn das nicht mit "STR" funzt besser #define STR "Hallo" // und nur z.B. printf(STR) benutzen ------------------------------------------------------------------------ C++BUILDER ---Abfragen/Belegen von Eigenschaften (BSP): EditN -> Text = char* oder AnsiString oder "Text " LabelN -> Caption = char* oder AnsiString oder "Text " ---LISTBOX ListBoxN -> Items -> Clear(); ListBoxN -> Items -> Add(String oder AnsiString); ListBoxN -> ItemIndex // = int ListBoxN -> ItemIndex = N; // select Item (0-N) ---Key abrage (z.B. OnKeyDown): if (Key == VK_ESCAPE) {... oder \r: if (Key == 13) {.. // 16=Shift 18=Alt Pfeil n.oben=38 u.=40 l.=37 r.=39 // Bild n.Oben=33 u.=34 Pos1=36 End=35 Einf.=45 entf.=46 für die maus gilt Button == mbRight ---OPEN/SAVE DIA SaveDialogN -> FileName = dateipfad; SaveDialogN->Execute(); // öfnet Dia, return 1 wenn OK ---AnsiString/String String = AnsiString.c_str(); // extrahiert Text aus AnsiString //**** BSP char temp_str[10]; strcpy (temp_str, Edit1->Text.c_str()); itoa (int, char*, 10); strcpy(char*,char*); bzw. strcpy(char*,"Text "); strcat(char*,char*); bzw. strcat(char*,"Text "); if(!strcmp(char*,"einheit")) ....; // return 0, wenn gleich Prozess wait, pause, sleep: C++B: _sleep(sekunden); (#include ) gcc : sleep(sekunden); ---Externe Programme starten #include int pid = spawnlp(P_NOWAIT,"J:\\Programme\\Internet Explorer\\IEXPLORE.EXE", " www.innocens.de",NULL); P_WAIT Der übergeordnete Prozeß bleibt im Speicher, wird aber für die Dauer der Ausführung des untergeordneten Prozesses angehalten. P_NOWAIT Die Ausführung des übergeordneten Prozesses wird nach dem Start des untergeordneten Prozesses fortgesetzt. Die Prozeß-ID des untergeordneten Prozesses wird zurückgeliefert, so daß der übergeordnete Prozeß über eine Aufruf von cwait oder wait auf das Ende des untergeordneten Prozesses warten kann. P_NOWAITO Entspricht P_NOWAIT mit der Ausnahme, daß die ID des untergeordneten Prozesses vom Betriebssystem nicht gespeichert wird. Daher kann der übergeordnete Prozeß nicht mit cwait oder wait auf das Ende des untergeordneten Prozesses warten. P_DETACH Entspricht P_NOWAITO mit der Ausnahme, daß der untergeordnete Prozeß im Hintergrund ohne Tastatur- und Bildschirmzugriff ausgeführt wird. P_OVERLAY Der übergeordnete Prozeß wird vom untergeordneten Prozeß im Speicher überlagert und nach dessen Beendigung nicht fortgesetzt. Dies entspricht dem Aufruf einer exec...-Funktion. p Die spawn-Funktion sucht nach dem untergeordneten Prozeß nicht nur innerhalb des aktuellen Verzeichnisses, sondern auch in sämtlichen durch die Umgebungsvariable PATH festgelegten Verzeichnissen. Die Varianten ohne das Suffix p suchen nur innerhalb des aktuellen Verzeichnisses. l Die Argumentzeiger arg0, arg1, ..., argn werden als separate Argumente übergeben. Das Suffix l wird normalerweise verwendet, wenn die Zahl der Parameter vorher bekannt ist. v Die Argumentzeiger argv[0], ..., arg[n] als Zeiger-Array übergeben. Diese Form wird normalerweise verwendet, wenn die Anzahl der Parameter variabel ist. e Erlaubt die Übergabe des Zeiger-Array envp (d.h. eines eigenen Environment für den untergeordneten Prozeß). Ohne das Suffix e erbt der untergeordnete Prozeß das Environment des übergeordneten Prozesses. (muß l oder v!!) ---beliebiges Bild in der Komponente TImage anzeigen: // für *.jpg muß ein #include "jpeg.hpp" gemacht werden Image1->Picture->LoadFromFile("C:\\bogen.jpg"); sowas gibt es auch dazu: Image1->AutoSize = true; // strecht ramen auf Größe des Bildes Image1->Stretch = true; // passt Bild dem Ramen an...verzerrt ---SystemTrayIcons: 1) Komponente -> win32 -> ImageList (ImageList1) 2) doppelcklick ImageList1 -> icons laden 3) Komponente -> Beispiele -> TrayIcon 4) in Eigenschaften -> Icons -> mit ImageList1 verbinden //leider noch nicht herausgefunden wie in Laufzeit möglich ... natürlich auch popup möglich (nicht vergessen in Option darunter zu aktivieren 5) TrayIcons Ereignisse entsprechend besetzten ---MESSAGEBOX Application->MessageBox("Abbrechen?", "erbrechen?", MB_OK); TApplication::HintPause // Zeit bis zum Einblenden TApplication::HintHidePause // Einblenddauer (millisek. ---Compilerspezifische Probeleme Übersetzen ohne dass *.bpr gebraucht werden: Project -> Optionen -> Packages -> NICHT mit Laufzeitpackages compilieren Übersetzen ohne dass *.dll gebraucht werden: Project -> Optionen -> Linker -> NICHT dynamische RTLs verwenden -------------(oft gebrauchte) BEISPIELE // datum und zeit besorgen #include #include int main(void) { struct date d; getdate(&d); printf("The current year is: %d\n", d.da_year); printf("The current day is: %d\n", d.da_day); printf("The current month is: %d\n", d.da_mon); return 0; } //------------------------- // Wort für Wort eines srings ausgeben void main (void) { char her_damit[50]; do gib_next_wort(her_damit) while (?); } //------------------------- int gib_next_wort(char* wort) { int stringlng = 0; int next_line = 0; static int mem_next_line = 0; char zeichen; char* wort_stack; wort_stack = wort; if (mem_next_line) next_line = 1; zeichen = fgetc (str_in); while (zeichen == ' ' || zeichen == '\t') zeichen = fgetc (str_in); while (zeichen != ' ' && zeichen != '\n' && zeichen != EOF && zeichen != '\t') { *wort_stack++ = zeichen; stringlng++; zeichen = fgetc (str_in); // if (zeichen == 0xa) { // für DOS formatierte Texte // wort_stack--; // } } *wort_stack = '\0'; if (zeichen == '\n'){ mem_next_line = 1; } else if (zeichen == EOF){ fclose(str_in); // fclose(str_out); } if (next_line) mem_next_line = 0; return next_line; } weil's so schön war... ...hier werden jtzt auch tags und anfürungzeichen berücksichtigt und < > werden in "" nicht berücksichtigt ausserdem ist die leseroutine durch do...while verbessert int __fastcall TForm1::gib_next_wort(char* wort, char *str) { int in_tag = 0; int in_mark = 0; static int mem_in_tag = 0; static int mem_in_mark = 0; // static int chr_nr = 0; // global vereinbart int mem_chr_nr; char* wort_stack; wort_stack = wort; in_tag = mem_in_tag; in_mark = mem_in_mark; if (!chr_nr) { //reset, wenn neue seite..zur fehlertoleranz mem_in_tag = 0; mem_in_mark = 0; } while (str[chr_nr] == ' ' || str[chr_nr] == '\t' || str[chr_nr] == '\n' || str[chr_nr] == '>' || str[chr_nr] == '"' || str[chr_nr] == '\r' || str[chr_nr] == '\'') { if (str[chr_nr] == '"') { if (in_mark) { mem_in_mark = 0; in_mark = 0; } else { mem_in_mark = 1; in_mark = 1; } } if (str[chr_nr] == '<' && !in_mark) mem_in_tag = 1; if (str[chr_nr] == '>' && !in_mark) { mem_in_tag = 0; in_tag = 0; } chr_nr++; } mem_chr_nr = chr_nr; do { *wort_stack++ = str[chr_nr++]; if (str[chr_nr-1] == '\\') *wort_stack--; } while (str[chr_nr] != ' ' && str[chr_nr] != '\n' && str[chr_nr] != '\t' && str[chr_nr] != '"' && str[chr_nr] != '\r' && str[chr_nr] != '\0' && str[chr_nr] != '>' && str[chr_nr] != '<' && str[chr_nr] != '\''); if (str[chr_nr] == '"') { if (in_mark) { mem_in_mark = 0; } else { mem_in_mark = 1; } chr_nr++; } if (str[mem_chr_nr] == '<' && !in_mark){ in_tag = 1; mem_in_tag = 1; } if (str[chr_nr] == '>' && !in_mark){ mem_in_tag = 0; } if (str[chr_nr] == '\0') { chr_nr = 0; } *wort_stack = '\0'; return in_tag; } //-------------------------------------------------------------- //BSP http dialog // commands können sein: // "GET /index.html" // "GET /index.html HTTP/1.1\r\nHost: www.nase.de\r\n\r\n" wenn's net funzt bis hin zu // "GET /index.html HTTP/1.1\r\nAccept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-powerpoint, application/vnd.ms-excel, application/msword, */*\r\nAccept-Language: de\r\nAccept-Encoding: gzip, deflate\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)\r\nHost: www.nase.de\r\nConnection: Keep-Alive\r\n\r\n"); int __fastcall TForm1::Execute(char *command, char *daten) { bool Terminated = false; int Count = 1500; char* daten_stack; daten_stack = daten; FILE *out; int real_length; int absolut_length =0; int re = 0; TWinSocketStream *pStream = new TWinSocketStream(ClientSocket1->Socket, 60000); try { // Befehle abrufen und verarbeiten, bis die Verbindung oder der Thread beendet ist while (!Terminated && ClientSocket1->Active) { try { // GetNextRequest(buffer); // GetNextRequest muß eine thread-sichere Methode sein // Die Anforderung auf den Server schreiben for (int i=0; i<5 && re < 1; i++) re = pStream->Write(command, strlen(command) + 1); // Die Kommunikation fortsetzen (z.B. eine Antwort vom Server lesen) do { real_length = pStream->Read(daten_stack, Count); daten_stack+=real_length; absolut_length += real_length; } while (real_length); // if (!real_length) Terminated = true; if (!real_length) ClientSocket1->Active = false; } catch (Exception &E) { int i=5; if (!E.ClassNameIs("EAbort")) ; // Synchronize(HandleThreadException()); // muss noch die HandleThreadException schreiben } } } __finally { delete pStream; } return absolut_length; } //----------------------------------------------------------------------------------------- ein UDP-Sender 1) Komponente -> FastNet -> NMUDP auf Formular 2) irgendwo die Eigenschaften: RemoteHost, RemotePort bestimmen z.B. Objectinspector oder einfach: NMUDP1->RemoteHost = "192.168.0.99"; NMUDP1->RemotePort = 1777; 3) dann sind mit: NMUDP1->SendBuffer("Text\0",9,9); // Telegramme zu verschicken //--------------------------------------------------------------------------- ein UDP listener: 1) Komponente -> FastNet -> NMUDP auf Formular 2) NMUDP1 -> Erignisse -> OnDataReveive -> funktion (z.B. read) eintragen 3) Eigenschaft "LocalPort" im Objectinspector nicht vergessen!! void __fastcall TForm1::read(TComponent *Sender, int NumberBytes, AnsiString FromIP, int Port) { char in_put[1024]; Form1 -> Visible = false; NMUDP2->ReadBuffer(in_put, 1024, NumberBytes); switch (in_put[0]) { case '0': ...; break; case 'r': ...; break; // u.s.w. default :break; } }