C windowskonsolen programm



  • Hallo!
    Ich bin ein Neuling in C. Bis jetzt habe ich nur ein paar Funktionen und kleinere Programme zur verschieden berechnungen gemacht. Nun habe ich ein größßeres Problem, leider aber keine Antworten in den FAQ's hier gefunden, da auch schon einige links dort tot sind.

    Es geht darum, in C mit der Konsole ein Wettrennen von 2 Buchstaben zu simulieren. Für die Schleifen und Zufallsfunktionen habe ich schon genug hintergrundwissen, aber leider fehlt mir völlig der Ansatz, wie ich dynamisch die 2 Buchstaben bewegen soll, geht das überhaupt mit Printf? Sie sollen von links nach rechts wandern.

    Könnt emir bitte jemand eine Erklärung geben?

    Vielen dank!



  • Dieser Thread wurde von Moderator/in SeppJ aus dem Forum C (C89 und C99) in das Forum DOS und Win32-Konsole verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Du könntest es so machen: Zeichne Buchstaben an ihrer aktuellen Pos. mit printf(), warte mit Sleep() einige Millisekunden, lösche den Bildschirm und fang wieder von vorne an.



  • Ultimativ!
    Vielen dank, hab ich heute nacht gleich umgesetzt, als ich wusste wonach ich suchen musste, gings sehr schnell.

    #include "stdio.h"
    #include "stdlib.h"
    #include "time.h"
    #include "windows.h"
    #include "conio.h"
    
    void platz2()
    	{
    	int p=196;
    	int r=0;
    	int s=0;
    	char *feld1 = (char *) malloc(sizeof (char) * 70);
    	char *feld2 = (char *) malloc(sizeof (char) * 70);
    
    	for (s =0;s<70;s++)
    	{
    		if (s==0 || s==69) 
    		{ feld1[s]=':';
    			feld2[s]=':';
    			feld2[s]=':';
    			feld1[s]=':';
    		}
    		else {
    			feld1[s]=' ';
    			feld2[s]=' ';
    		}
    	}
    
    	for (r=0;r<70;r++)
    	{
    		printf("%c",p);
    	}
    	printf("\n");
    	for (s=0;s<70;s++)
    	{
    		printf("%c",feld1[s]);
    	}
    	printf("\n");
    	for (s=0;s<70;s++)
    	{
    		printf("%c",feld2[s]);
    	}
    	printf("\n");
    	for (r=0;r<70;r++)
    	{
    		printf("%c",p);
    	}
    	printf("\n");
    	}
    
    int main(int argc, char *argv[])
    {
    
      int iz;//igelzufallszahl
      int hz;//hasezufalls zahl
      int i;
      srand(time(0)); //für zufallsfunktion
       int u=0;
       int t=0;
    	int p=196;
    	int r=0;
    	int s=0;
    	char *feld1 = (char *) malloc(sizeof (char) * 70);
    	char *feld2 = (char *) malloc(sizeof (char) * 70);
    
    	puts("HIER kommen die zeichen");
    
    	platz2();
    
    printf("und los gehts");
    
    Sleep(10000);
    
    while ( (u<69) && (t<69))
    
      {
    
    	  //hase!!
    
    	  hz=1+(rand() % (11-1));
    
    	  if (hz<=2)
    		  t=t+0;
    	  if (hz>=3 && hz<=4)
    		  t=t+9;
    	  if (hz==5)
    		  t=t-12;
    	  if (hz>=6 && hz<=8)
    		  t=t+1;
    	  if (hz>=8 && hz<=10)
    		  t=t-1;
    
    	 //IGEL!!!
    
    	iz=1+(rand() % (11-1));
    	  if (iz<=5)
         		 u=u+3;
    		//3 schritte
    
      if (iz>=6 && iz<=7)
      	  u=u-6;
    	  //6schritte zur
    
      else if (iz>7)
    	  u=u+1;
    	 //1 schritt vor
    
    	if (u<0)
    		u=0;
    	if (u>69)
    		u=69;
    	if (t<0)
    		t=0;
    	if (t>69)
    		t=69;
    
         feld1[u]='I';
    	 feld2[t]='H';
    
    	system("cls");
    
    	//IGEL!!
    
    		for (s=0;s<u;s++)
    	{
    			if (s==0) 
    		feld1[s]=':';
    
    		else 
    			feld1[s]=' ';
    
    	}
    	for (s=u+1;s<70;s++)
    	{	
    			if ( s==69) 
    		 feld1[s]=':';
    
    		else 
    			feld1[s]=' ';
    	} 
    
    	//HASE!!!
    
    	for (s=0;s<t;s++)
    	{
    			if (s==0) 
    		feld2[s]=':';
    
    		else 
    			feld2[s]=' ';
    
    	}
    	for (s=t+1;s<70;s++)
    	{	
    			if ( s==69) 
    		 feld2[s]=':';
    
    		else 
    			feld2[s]=' ';
    	}
    
    	for (r=0;r<70;r++)
    	{
    		printf("%c",p);
    	}
    	printf("\n");
    	for (s=0;s<70;s++)
    	{
    		printf("%c",feld1[s]);
    	}
    	printf("\n");
    	for (s=0;s<70;s++)
    	{
    		printf("%c",feld2[s]);
    	}
    	printf("\n");
    	for (r=0;r<70;r++)
    	{
    		printf("%c",p);
    	}
    	printf("\n");
    
    	if ( t==u && u>0 && u<69)
    		printf(" AUA der Igel is firing ma lazOOOr");
    
    	printf("t:%d und u;%d",t,u);
    	Sleep(1000);
      } 
    
      system("PAUSE");	 
      return 0;
    }
    

    hab das soweit umgesetzt, viellleicht gibt es noch ein paar tipps, das gnaze schlanker und einfacher zu machen? 😉

    frohe weihnachten !



  • Man kann deinen Quellcode garantiert schlanker machen. Allerdings ist dieser sehr unübersichtlich und was da genau berechnet wird, das wird einem auch nicht sofort klar. Außerdem ist dein Quellcode kein echtes C. Aus dem Stehgreif hätte ich es irgendwie so gelöst:

    #include <stdio.h>
    #include <Windows.h>
    
    int main()
    {
    	int igel = 0;
    	int hase = 0;
    	int i;
    
    	srand((unsigned int) time(NULL));
    
    	while (hase <= 70 && igel <= 70)
    	{
    		printf("----------------------------------------------------------------------\n");
    
    		for (i = 0; i < igel; ++i)
    			putchar(' ');
    
    		printf("I\n");
    
    		for (i = 0; i < hase; ++i)
    			putchar(' ');
    
    		printf("H\n");
    
    		printf("----------------------------------------------------------------------\n\n");
    
    		if (igel > hase)
    		{
    			printf("Igel fuehrt!\n");
    		}
    		else if (igel < hase)
    		{
    			printf("Hase fuehrt!\n");
    		}
    		else
    		{
    			printf("Beide sind gleichauf!\n");
    		}
    
    		igel += rand() % 9;
    		hase += rand() % 11;
    
    		Sleep(1000);
    
    		system("cls");
    	}
    
    	if (igel > hase)
    	{
    		printf("Der Igel hat gewonnen!\n");
    	}
    	else if (igel < hase)
    	{
    		printf("Der Hase hat gewonnen!\n");
    	}
    	else
    	{
    		printf("Unentschieden!\n");
    	}
    
    	return 0;
    }
    

    Dein Quellcode enthält übrigens Speicherleaks, da du den angeforderten Speicher (malloc) nicht wieder freigibst (free). Aber das Array ist auch nicht zwangsläufig notwendig und wenn, dann hättest du es auch ganz einfach mit char feld1[70]; anlegen können und hättest so erst gar kein Speicher reservieren brauchen.

    Insgesamt ist deine Einrückung auch nicht sehr konsequent. Mal ist es so eingerückt und mal so. Das ist für die Lesbarkeit nicht sonderlich förderlich.

    Anstatt printf("%c", p); könntest du übrigens auch putchar(p); schreiben.

    Beim Inkludieren solltest du für Header, die außerhalb deines Projektes liegen die spitzen Klammern verwenden. Damit sucht der Prozessor in den vorgegebenen Include-Verzeichnissen und erst danach im Projektverzeichnis. Bei den " ist es genau andersrum. Hier wird erst im Projektverzeichnis gesucht.



  • Noch ein Tipp:

    Anstatt t = t + 1; kann man auch t += 1; bzw. t++; oder ++t; schreiben (Ob man ++t; oder t++; schreibt macht als alleinstehende(!) Anweisung aber keinen wirklichen Unterschied).



  • Zum Stil usw. hat jlkjkl eigentlich schon alles gesagt.
    Aber eine Verbesserung hätte ich auch noch: system("cls"); ist böse. Nimm lieber FillConsoleOutputCharachter



  • Na, dann aber auch bitte gleich:
    SetConsoleCursorPosition und
    WriteConsoleOutputCharacter

    zum Cursorpositionieren und Zeichen ausgeben - dann kann man sich übrigens auch das Bildschirmlöschen ganz sparen ...



  • danke für die vielen Antworten. Hatte nicht damit gerechnet soviel feedback zu bekommen. @ jlkjkl, das mit den <> klammern ging bei mir nicht, wir müssen Visual studio benutzen... die anderen tipps werde ich versuchen umzustezen! die aspeicherfreigabe müsste am ende gesetzt werden dann?

    die befehle mit der cursor posítion und buchstaben an positionen schreiben hatten wir noch nicht..
    Das ganze ist ein kleines uni projekt in grundlagen und naja, es gibt da bestimmte vorgaben wann welcher teilnehmer wie viele schritte machen soll..
    Auf jedenfall vielen dank für die ideen!

    Ist das nicht mehr aufwand, die cursor zu positionieren, statt alles zu löschen? es wäre sicher speicher sparender... 😉



  • Mosh3d schrieb:

    @ jlkjkl, das mit den <> klammern ging bei mir nicht, wir müssen Visual studio benutzen...

    Ich benutz auch VS. Und das mit den spitzen Klammern funktioniert dort auch! Hast du etwa an den Einstellungen rumgespielt? Wenn ja müsstest du schon ganz schön was verstellt haben, damit das nicht mehr funktoiniert. Kompilier mal mit <> und dann Poste bitte den Fehlercode.

    Mosh3d schrieb:

    die befehle mit der cursor posítion und buchstaben an positionen schreiben hatten wir noch nicht...

    Trotzdem: Vorausarbeiten kann nichz schaden. 🙂
    Was mir grad auffällt: Habt ihr system("cls"); etwa an der Uni gelernt? Wenn ja, dann darfst du von diesem Prof. nicht allzuviel erwarten. Und falls er mal ein Buch von einem gewissen Autor anpreisen sollte (den ich nicht nennen möchte, damit du gar nicht erst in Versuchung kommst dir eins seiner Bücher anzusehen die mehr schaden als nützen), dann hör lieber nicht auf ihn.

    Mosh3d schrieb:

    1) Ist das nicht mehr aufwand, die cursor zu positionieren, statt alles zu löschen? 2) es wäre sicher speicher sparender... 😉

    Zu 1: Richtig gemacht ist es weniger Aufwand.
    Zu 2: Äh nö, warum sollte das Speicher sparen? 😕



  • also in <> klammern kommt der fehler, dass die bibliothek nicht gefunden werden kann. Ich hab geschrieben #include <stdio.h> z.b... ist das falsch?

    ich werd das nochmal überarbeiten, so ähnlich wie jlkjkl, mit der cursor positionierung un d löschung :>

    danke für die hilfe!



  • #include <stdio.h>
    

    ist eigentlich richtig. Probier mal testweise cstdio (kein .h!) statt stdio.h. Ist dann zwar C++, aber is ja nur zum Test.
    Wobei Bibliothek nicht gefunden eher nach nem Linker-Problem klingt. Kopier mal die gesamte Erstell-Ausgabe in Code-Tags hierher, denn Link-Probleme dürften eigentlich nicht durch fehlerhafte Header-Einbindung passieren. Hast du die Einstellungen für ein Win32-Konsolen-Projekt gesetzt?



  • es funktioniert jetzt eigentlich ganz gut ... aber!

    wir sollen nun das programm mit parametern starten.

    ich habe dazu

    sscanf(argv[1],"%d",&vi);
    	sscanf(argv[2],"%d",&vh);
    
    	if((vi>0&&vi<20) || (vh>0&&vh<20)) //falls parameter verwendet werden
    	{
    		hase = vh; //erhöhung von hase
    		igel = vi; //erhöhung von igel
    	}
    

    gemacht,es geht auch wenn man es MIT parameter startet einwandfrei, aber wenn man ohne parameter eingabe es startet, stürzt das programm ab... jemand eine idee? bitte?



  • argc hat auch seine Bedeutung. Wenn keine Parameter übergeben wurden, dann kannst du folglich auch nicht auf argv[1] zugreifen (bzw. gehört dir der Speicher nicht und du rufst undefiniertes Verhalten hervor).
    Die Lösung ist ganz banal:

    //...
    if(argc == AnzahlDerArgumente)
    {
        //...
        //mach was mit argv
    }
    else
    {
        cout << "Fehler beim Aufruf. Falsche Parameterzahl\n";
    }
    //...
    

    EDIT: Was war eigentlich das Problem bei den Headern, bzw. wie hast dus gelöst?



  • ach argc hab ich total vergessen, danke!

    mit den headern, war die lösung einfach, ich habs gelassn 🙂


Anmelden zum Antworten