Probleme mit einer Steuerung
-
guten abend zusammen..
vorab erstmal meine c kenntnisse halten sich ein wenig in grenzen da ich erst vor ca 2 monaten angefangen habe mich hobbymaessig damit zu beschaeftigen..
naja, mein cheff hat wind davon bekommen und kam auf die gloreiche idee das ich ein programm fuer seine anzeige tafel programmieren sollte..
die verbindung von pc zu dem display is ueber lan..soweit so gut.. mein programm funktioniert auch mehr oder weniger..
also das mit dem senden und so klappt gut, nur mit der bediehnung des programms
harkt es noch..als compiler nutze ich dev-c++
zb wenn ich bei der menueauswahlanstatt eine zahl einen buchstaben eingebe haengt sich das programm auf..
und 2 andere dinge die mich stoeren die im quelltext makiert sind
//********************************************* //** E I N G A B E F U E R D I S P L A Y ** //********************************************* //******************* //* INCLUDE - FILES * //******************* #include <string.h> #include <stdio.h> #include <stdlib.h> #include <Winsock2.h> #include <time.h> #include <sys/timeb.h> #include <ctype.h> short const MODE_TCP = 1; short const MODE_UDP = 2; void USAGE(char* name){ printf("Anleitung fuer %s\n",name); printf("%s [-a <display-ip>] [-p <display-port>] [-r <update-rate>] [-m {tcp|udp}]\n\n",name); } main(int argc, char** argv) { char** argPtr = argv; int dspSocket = 0; char* address = "192.168.10.200"; short port = 8000; int rate = 5; short mode = MODE_UDP; int error; struct sockaddr_in dspAddress; char timeStr[20]; struct tm* myTm; struct _timeb tstruct; int index; char cmd[6] = { 0x1b, 0x31, 0x30, 0x31, 0x31,0x00}; char buf[61]; char rbuf[5]; WORD wVersionRequested; WSADATA wsaData; int err; fd_set rfds, wfds; int retval; struct timeval timeout = {0, 0}; int sleeptime; int sockErr; int size = 0; short srcPort = 0; char srcName[25] = "C"; short cmdLen = 0; char eingabe[55]; int wahl; int x; char ende[1]; int heim; int gast; char spiel[20]; int b; int a; wVersionRequested = MAKEWORD( 1, 1 ); err = WSAStartup( wVersionRequested, &wsaData ); if ( err != 0 ) { exit(1); } // *********************************** // *P A R A M E T E R - E I N G A B E* // *********************************** while(*argPtr){ if(**argPtr == '-'){ if(strcmp(*argPtr,"-a")==0){ address = *++argPtr; } else if(strcmp(*argPtr,"-p")==0){ port = atoi(*++argPtr); } else if(strcmp(*argPtr,"-r")==0) { rate = atoi(*++argPtr); sleeptime = 1000/rate; } else if(strcmp(*argPtr,"-m")==0){ ++argPtr; if(strcmp(*argPtr,"tcp")==0){ mode = MODE_TCP; } else { mode = MODE_UDP; } } else { USAGE(argv[0]); exit(1); } } ++argPtr; } // ******************* // * V E R B I N D E * // ******************* memset(&dspAddress, 0, sizeof(struct sockaddr)); dspAddress.sin_family = AF_INET; dspAddress.sin_addr.s_addr = inet_addr(address); dspAddress.sin_port = htons(port); printf ("\n\n*************************************\n"); printf ("* D I S P L A Y S T E U E R U N G *\n"); printf ("*************************************\n\n"); printf ("Verbindung wird hergestellt...\n\n"); if(mode == MODE_TCP){ if( (dspSocket = socket(AF_INET,SOCK_STREAM,0) ) < 0){ error = WSAGetLastError(); fprintf(stderr,"Keine Verbindung ueber TCP moeglich!\n"); gets (ende); exit(1); } } else { if( (dspSocket = socket(AF_INET,SOCK_DGRAM,0) ) < 0){ error = WSAGetLastError(); fprintf(stderr,"Keine Verbindung ueber UDP moeglich!\n"); gets (ende); exit(1); } } if( connect(dspSocket,(struct sockaddr*)&dspAddress,sizeof(struct sockaddr) ) < 0){ printf("Verbindung zu %s : %d konnte nicht hergestellt werden!\n",address,port); printf("Bitte ueberpruefen Sie ob das das Geraet richtig\n"); printf("angeschlossen wurde.\n"); printf("Eingabetaste beendet das Programm\n"); gets (ende); exit (1); } size = sizeof(struct sockaddr); getsockname(dspSocket,(struct sockaddr*)&dspAddress,&size); printf ("Verbindung zu %s : %d unter Verwendung des Protokolls %s \n",address,port,mode == MODE_TCP?"TCP":"UDP"); printf ("hergestellt.\n"); while(1){ printf ("\n\n***********************\n"); printf ("* H A U P T M E N U E *\n"); printf ("***********************\n\n"); printf("Bitte waehlen Sie einen Modus:\n"); printf("1 Waehlen Sie fuer eine Spielstand-Anzeige\n"); printf("2 Waehlen Sie fuer die aktuelle Uhrzeit\n"); printf("3 Waehlen Sie fuer eine beliebige Eingabe\n"); printf("0 Beendet das Programm.\n"); printf("Bestaetigen Sie Ihre Wahl mit der Eingabgetaste\n\n"); scanf ("%i",&x); if (x==0){ exit(1); } // *************************************** // * S P I E L S T A N D - A N Z E I G E * // *************************************** else if (x==1){ cmd[2]= 0x2F; a = 1; heim = 0; gast = 0; while (a==1) { printf ("\n\n*****************************************\n"); printf ("* S P I E L S T A N D - A N Z E I G E *\n"); printf ("*****************************************\n\n"); printf ("Fuer neuen Spielstand bitte die 1 druecken\n"); printf ("Zum Beenden bitte die 0 waehlen\n"); printf ("Mit Eingabetaste bestaetigen.\n\n"); scanf ("%i",&b); if (b == 1){ printf ("\nAktueller Stand Heim:"); scanf ("%i",&heim); printf ("\nAktueller Stand Gast:"); scanf ("%i",&gast); sprintf (buf,"\r"); sprintf (spiel,"Home %i:%i Guest\r",heim,gast); } else if (b == 0){ if (heim == gast){ sprintf (spiel,"Unentschieden\r"); } else{ sprintf (spiel,"%s has Win\r",heim>gast?"Home":"Guest"); } cmd[2] = 0x2E; a=2; } else { printf ("\n\nUngueltige Wahl\a\n"); } strcat(buf,cmd); cmdLen = strlen(buf); index = strlen(spiel); FD_ZERO(&rfds); FD_ZERO(&wfds); FD_SET(dspSocket,&rfds); FD_SET(dspSocket,&wfds); strcpy(buf+cmdLen,spiel); // S E N D E D A T E N if(send(dspSocket,buf,strlen(buf)+1,0) == SOCKET_ERROR){ printf("Sendefehler!\n"); } if(send(dspSocket,buf,strlen(buf)+1,0) == SOCKET_ERROR){ printf("Sendefehler!\n"); } } } // *********** // * Z E I T * // *********** else if(x==2){ printf ("\n\n***********\n"); printf ("* Z E I T *\n"); printf ("***********\n\n"); cmd[2] = 0x30; size = sizeof(struct sockaddr); getsockname(dspSocket,(struct sockaddr*)&dspAddress,&size); srcPort = ntohs(dspAddress.sin_port); sprintf(buf,"\r"); strcat(buf,cmd); cmdLen = strlen(buf); while(1){ // hier brauche ich einen befehl der die schleife unterbricht, // aber nur wenn ich eine taste druecke und // der hier nicht auf die eingabe wartet // sondern weitermacht, wenn keine eingabe kommt... Sleep(sleeptime); _ftime( &tstruct ); myTm = gmtime(&tstruct.time); strftime(timeStr,14,"%j.%H:%M:%S.",myTm); index = strlen(timeStr); sprintf(timeStr+index,"%03d",tstruct.millitm); timeStr[16]='\r'; timeStr[17]=0; strcpy(buf+cmdLen,timeStr); FD_ZERO(&rfds); FD_ZERO(&wfds); FD_SET(dspSocket,&rfds); FD_SET(dspSocket,&wfds); retval = select(dspSocket+1, 0, &wfds, 0, &timeout); // S E N D E D A T E N if(retval > 0){ if(send(dspSocket,buf,strlen(buf)+1,0) == SOCKET_ERROR){ printf("Sendefehler!\n"); } retval = select(dspSocket+1,&rfds, 0, 0, &timeout); if(retval > 0){ if(recv(dspSocket,rbuf,5,0) == SOCKET_ERROR){ printf("Sendewiederholung: Fehler aufgetreten!\n"); sockErr = WSAGetLastError(); printf("Fehler-Code = %d\n",sockErr); } } } } } // *************************** // * T E X T - E I N G A B E * // *************************** else if (x==3){ printf ("\n\n***************************\n"); printf ("* T E X T - E I N G A B E *\n"); printf ("***************************\n\n"); printf("Bitte geben Sie den Text ein:\n"); scanf ("%s",&eingabe); // so nimmt er natuerlich nur 1 wort an, // bzw nach einem leerzeichen zeigt er nur das letze wort an... // gets(eingabe); // so ueberspringt er die eingabe und gibt nichts aus.. printf("\n\nBitte waehlen sie die gewuenschte Darstellungsart:\n"); printf("Waehlen Sie die 1 fuer Blinkschrift zentriert\n"); printf("Waehlen Sie die 2 fuer Standschrift zentriert\n"); printf("Waehlen Sie die 3 fuer Standschrift linksbuendig\n"); printf("Waehlen Sie die 4 fuer Blinkschrift linksbuendig\n"); printf("Bestaetigen Sie Ihre Wahl mit der Eingabgetaste\n\n"); do{ scanf ("%i", &wahl); switch(wahl){ case 1: cmd[2] = 0x2E; break; case 2: cmd[2] = 0x2F; break; case 3: cmd[2] = 0x30; break; case 4: cmd[2] = 0x31; break; default: printf ("Ungueltige Auswahl!\a\n"); printf ("Bitte waehlen Sie erneut aus:"); } }while (wahl < 1 || wahl > 4); sprintf (buf,"\r"); strcat(buf,cmd); cmdLen = strlen(buf); index = strlen(eingabe); FD_ZERO(&rfds); FD_ZERO(&wfds); FD_SET(dspSocket,&rfds); FD_SET(dspSocket,&wfds); strcpy(buf+cmdLen,eingabe); // S E N D E D A T E N if(send(dspSocket,buf,strlen(buf)+1,0) == SOCKET_ERROR){ printf("Sendefehler!\n"); } if(send(dspSocket,buf,strlen(buf)+1,0) == SOCKET_ERROR){ printf("Sendefehler!\n"); } } else { printf("Ungueltige Wahl!\a\n"); } } }
kritik ueber struktur nehme ich auch gerne entgegen
danke schonmal
-
Hi,
ersetze Zeile 303 durch:
fgets(eingabe, 55, stdin);
Und füge hinter jedem scanf() ein
getchar();
an.
fgets liest höchstens 54 Zeichen bis ein nextline kommt.
scanf() liest das nextline zeichen nicht mit, daher das getchar().Zur zweiten Frage: mit break kommst du aus einer while schleife
wieder raus. Aber das ist nicht genau das, was du willst.Ich bin mir nicht so sicher, ob das alles so funktioniert, aber
du sagst ja, es tuts. Mit gcc -W -Wall -pedantic kompiliert bekomme
ich einige Warnings und Errors.Initialisiere x mit 5, damit eine Eingabe eines Buchstabens zu einer
ungültigen Eingabe führt.LG mcr
-
danke schonmal fuer deine hilfe, ich werds nach der schule probieren..
zum compiler:
das liegt wahrscheinlich an '<Winsock2.h>' du musst dafuer die libary libws2_32.a
dem projekt hinzufuegen
-
Ich arbeite zu 99.95% mit Linux und ich glaube, da habe ich diese Lib
nicht. Aber egal, ich habe es zum Kompilieren gebracht. Testen kann ich es
ja nur bedingt, da ich keinen Zugriff auf die Anzeige habe.Gruß mcr
-
kritik ueber struktur nehme ich auch gerne entgegen
Unterteile dein Programm in sinnvolle Teilfunktionen, anstatt alles in die main-Funktion zu packen.
Verwende dann auch nur die lokalen Variablen, wo du sie brauchst (bei der Menge an Variablen wirst du selber evtl. in einigen Monaten nicht mehr durchfinden).
-
danke euch schonmal, das programm laeuft soweit ganz gut..
jezz muesste ich nur noch das problem mit der uhr hinbekommen..
da das ja eine schleife ist, die sich dauernt wiederholt, um wirklich die aktuelle uhrzeit mit milisekunden auf dem display darstellt, braeuchte ich irgenteinen befehl, wo der nicht extra auf eine eingabe wartet, sondern wenn keine eingabe da ist, er weiter macht..
mhm.. wobei da auch wieder das problem ist, das ich dann genau zum richtigen zeitpunkt die eingabe machen muesste..
da komme ich nicht weiter.ist das ueberhaupt realisierbar?
zur struktur:
danke fuer deine tips, werde versuchen das so hinzubekommen
-
Bzgl. der Tastenabfrage. Schau mal nach, ob bei dir die Funktion kbhit() verfügbar ist? Wenn ja, dann kannst du hier im Forum (insb. im Konsolen-Subforum) nach Beispielen zur richtigen Benutzung suchen.