Duale Eingabe in C-Programm



  • Das steht mir leider nicht zur verfügung.
    Das Problem an der Sache ist, das die Eingabe der Codewörtern dynamisch gehalten ist. Ich realisiere momentan die Eingabe so:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    int main(void) {
       int *value;
       int size, i = 0;
       printf("Wie viele Werte benötigen Sie : ");
       scanf("%d", &size);
       value = (int *)malloc(size*sizeof(int));
       if( NULL == value ) {
          printf("Fehler bei malloc....\n");
          return EXIT_FAILURE;
       }
       while( i < size ) {
          printf("Wert für value[%d] eingeben : ", i);
          scanf("%d", &value[i]);
          i++;
       }
       printf("Hier Ihre Werte\n");
       for(i=0; i < size; i++)
          printf("value[%d] = %d\n", i, value[i]);
       return EXIT_SUCCESS;
    }
    

    Wie gesagt kann ich hier nur Integer-zahlen eingeben. Ich könnte das ganze zwar auch dynamisch in einen String-Array eingeben lassen, doch das möchte ich erhrlich gesagt nicht. Das liegt daran das mir das ansprechen über ein Integer-Array einfacher gelingt. Hier kann ich einfach über den index i bei value[i] das Codewort ansprechen, und an die Funktion Hamming übergeben.
    Da ich ja jedes Codewort mit jedem vergleichen muss.

    Würde ich das ganze über ein String array machen, müsste ich mittles einer Schleife immer bis zum CR (\0) die einzelnen Codeworte rausziehen und dann erst mittels atoi in eine Zahl umwandeln.

    Das wolte ich vermeiden, das Array immer wieder auf das CR zu überprüfen und die Codeworte zwischenzulagern.

    Wenn ich dies so machen würde könnte ich mir das umwandeln in eine Integer Zahl sparen und direkt an die Funktion Hamming übergeben und die Zeichen einzeln vergleichen lassen.

    Dies wiederum ist ein haufen Code den ich schreiben müsste, was ich eigentlich umgehen wollte, da eine direkte XOR-Verknüpfung von zwei Codeworten eleganter wäre statt der einzelnen Zeichen inerhalb der Codes.



  • doch das möchte ich erhrlich gesagt nicht.

    ... und begruendest es mit Lernfaulheit. Aber ich glaube, dir wird nichts anderes ueberig bleiben.

    erst mittels atoi in eine Zahl umwandeln

    Nein, das waere der falsche Weg, da dann das gleiche wie bei deinem jetzigen Versuch herauskaeme.



  • Was stört dich an einem String? Den kannst du ganz bequem von man: strtol in die richtige Zahl umwandeln lassen, dann musst du dir nur noch über die Ausgabe Gedanken machen.
    🙂



  • Was hälst du denn von sowas:

    int hoch(int x, int y){ //rechnet x hoch y
        int r;
        for(r=1; y>0; y--) r*=x;
        return r;
    }
    
    int bin(int x){ //rechnet Binärzahl in dezimaler Darstellung in Binärzahl um
        int r = 0;
        for(int stelle = 0; stelle<11; stelle++) //funktioniert nur mit 32Bit ints
            if (hoch(10, stelle) && x) r+=hoch(2, stelle);
        return r;
    }
    


  • knivil schrieb:

    doch das möchte ich erhrlich gesagt nicht.

    ... und begruendest es mit Lernfaulheit. Aber ich glaube, dir wird nichts anderes ueberig bleiben.

    Tut mir leid wenn du diesen eindruck hast, das hat nichts mit Lernfaulheit zu tun.
    Ich bin nur am überlegen was am effjektivsten ist. Da ich nicht unnötig vielen Code schreiben möchte wenns auch einfach geht. Ich könnte das ganze sicherlich auch über einen String Array machen, nur dann wäre der Quellcode um einiges größer als wenn ich es über ein Integer-Array machen könnte.

    Wenn ich später mal nen Controler Programmiere muss ich auch darauf achten den Quellcode so klein wie möglich zu halten, damit das Programm schnell und platzsparend abläuft.



  • Was ist denn heute nur los?

    char binstr[SIZE];
    fgets(binstr, SIZE, stdin);
    long zahl1 = strtol(binstr, NULL, 2);
    // wenn du das nochmal mit einem 'long zahl2' machst, dann geht das XOR so:
    long xored = zahl1 ^ zahl2;
    

    Wenn du statt NULL noch die Adresse eines char-Zeigers mitgibst, kannst du auch noch alle möglichen Fehler abfangen.

    Wenn ich später mal nen Controler Programmiere muss ich auch darauf achten den Quellcode so klein wie möglich zu halten, damit das Programm schnell und platzsparend abläuft.

    War das nicht kurz genug? Btw: was hat denn die Codegrösse mit der Laufzeit zu tun?
    🙂



  • damit das Programm schnell und platzsparend abläuft

    Und dann holst du so ein Monster wie scanf() an Bord?
    😕



  • µngbd schrieb:

    damit das Programm schnell und platzsparend abläuft

    Und dann holst du so ein Monster wie scanf() an Bord?
    😕

    Würde mich auf eine Erklärung freuen...
    Wie ist mit 'Monster' gemeint?



  • Da ich nicht unnötig vielen Code schreiben möchte wenns auch einfach geht.

    Dann nimm eine andere Sprache, C++ oder Java oder Haskell oder ... bieten sich an.

    Als Alternative von scanf bietet sich vielleicht die Moeglichkeit an, deine Binaerzahlen als String per Kommandozeilenargument einzugeben. Die Umwandlung erfolgt dann von hinten nach vorne, indem entweder eine 1 oder 0 (abhaengig vom char-Wert "1" oder "0") geshiftet wird. Oder du verwendest das schon angesprochene strol().



  • sunny31 schrieb:

    µngbd schrieb:

    Und dann holst du so ein Monster wie scanf() an Bord?
    😕

    Würde mich auf eine Eklärung freuen...
    Wie ist 'Monster' gemeint?

    Naja, scnaf() muss die ganze Logik irgendwo bereitstellen, um die Formatstring-Syntax zu verstehen. Wenn Speicher und Laufzeit knapp sind, könnte es sich schon mal auszahlen, scanf(), printf() und ihre Brüder ganz raus zu nehmen. Die gehören sicher zu den aufwändigsten Funktionen in der ganzen Standard-Bibliothek.

    Mir fällt das immer wieder ein, wenn ich sowas sehe:

    char c;
    scanf("%c", &c);    // statt getchar()
    // oder
    char s[SIZE];
    scanf("%s ", s);    // statt fgets()
    

    Das ist natürlich Wahnsinn. Zahlen einlesen ist ja noch in Ordnung, aber die Standard-Formatstrings können eben keine Binärdarstellungen, obwohl manche Compiler %b (für Binärdarstellungen) kennen. Dafür gibt es im Standard aber strtol().
    🙂



  • Chris12 schrieb:

    Wenn ich später mal nen Controler Programmiere muss ich auch darauf achten den Quellcode so klein wie möglich zu halten, damit das Programm schnell und platzsparend abläuft.

    dann mach dir doch 'ne funktion, die einen string aus nullen und einsen in eine zahl umwandeln kann, ist nicht mehr als ein drei- oder vierzeiler.

    knivil schrieb:

    Da ich nicht unnötig vielen Code schreiben möchte wenns auch einfach geht.

    Dann nimm eine andere Sprache, C++ oder Java oder Haskell oder ... bieten sich an.

    ich weiss ja nicht, ob haskell schnellen, kleinen maschinencode erzeugen kann, aber Java z.b. braucht im normalfall eine virtual machine o.ä. und c++ ...ähm, *räusper*
    🙂



  • fricky schrieb:

    ich weiss ja nicht, ob haskell schnellen, kleinen maschinencode erzeugen kann

    Glaub ich nicht. Das Ding ist lazy. Im besten Fall kommt wahrscheinlich immer noch eine riesige Runtime-Bib. dazu (ausser man baut alles aus den Axiomen zusammen, aber das ist wiederum eine epische Laufzeitverschwendung). Und den Compiler verstehen dann sicher nur mehr drei Leute auf der Welt.

    fricky schrieb:

    und c++ ...ähm, *räusper*

    C++ hat sicher irgendeinen Zauberspruch, den man zwischen cin und die Variable schreiben muss, damit die Zahl zur Basis 17 genommen wird. Fragt dann wahrscheinlich insgeheim bei strtol() nach, weil Zaubern gar nicht so einfach ist, und deshalb von einem Magier geerbt werden muss.
    🙂



  • Ok erstmal Danke für die nette Diskussion.
    Die anregungen haben mir geholfen mein Problem zu lösen.

    Leider darf ich keine andere Sprache als C nehmen. Da ich momentan im 1.Semester nur ANSI C behandele.

    Bisher haben wir da irgendwie überwiegend mit scanf gearbeitet, deshalb habe ich es benutzt. Ich poste mal meine bisherige Lösung, das Programm ist noch nicht fertig aber bin damit als ersten Zwischenschritt zufrieden.

    Vielleicht hat ja der ein oder andere noch ein paar optimierungs tips.

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #define BUF 255
    
    char HammingDistance(char Code[],char Code2[])
    {
    	int array_groese,Hamming;
    	char i;
    	char v[80]={' '};
    
        array_groese =0;
    	Hamming =0;
    
    	while (Code[array_groese]!='\0'){array_groese++;}//Größe des String-Arrays bestimmen
    	for (i=0;i<=array_groese-1;i++){if ((Code[i]^Code2[i])==1){Hamming=Hamming+1;}}
    	printf("Haben die Hamming Distance : %d\n",Hamming);
    	printf("\n");
    
    	return(Hamming);
    }
    
    void Sort(int value[],int CodewörterAnzahl)
    {
       int i,j;
       char buf[BUF];
       char buf2[BUF];
    
       //Vergleicht alle Codewörter mit einander
       for(i=0;i<=CodewörterAnzahl-1;i++)
       {
    	   for(j=(i+1);j<=CodewörterAnzahl-1;j++)
    	   {
    		   itoa(value[i], buf, 10);
    		   itoa(value[j], buf, 10);
    		   printf("Codewort %d & Codewort %d\n",value[i],value[j]);
    		   HammingDistance(itoa(value[i], buf, 10),itoa(value[j], buf2, 10));
    	   }
       }
    }
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    int main(void) {
       int *value;
       int size, i = 0;
       printf("Wie viele Werte benötigen Sie : ");
       scanf("%d", &size);
       value = (int *)malloc(size*sizeof(int));
       if( NULL == value ) {
          printf("Fehler bei malloc....\n");
          return EXIT_FAILURE;
       }
       while( i < size ) {
          printf("Wert für value[%d] eingeben : ", i);
          scanf("%d", &value[i]);
          i++;
       }
       printf("Hier Ihre Werte\n");
       for(i=0; i < size; i++){
    	   printf("value[%d] = %d\n", i, value[i]);}
    
       Sort(value,size);
    
       return EXIT_SUCCESS;
    }
    


  • Ich habe jetzt nur noch ein Problem:
    Wenn ich 0100 eingeben wird an die Funktion 100 übergeben was mir auch logisch erscheint. Wie könnte ich die führende 0 erhalten?



  • µngbd schrieb:

    ... ... ...

    Wie immer bin ich dir dankbar für deine Erklärungen. :xmas1:



  • Vielleicht hat ja der ein oder andere noch ein paar optimierungs tips.

    Warum nicht int 's (oder sowas) für die Zahlen nehmen und das XOR den Prozessor in einem Schritt machen lassen? Dann könntest du dir den ganzen itoa()-Wahnsinn sparen. Der ist nämlich echt völlig unnötig.
    🙂



  • µngbd schrieb:

    Vielleicht hat ja der ein oder andere noch ein paar optimierungs tips.

    Warum nicht int 's (oder sowas) für die Zahlen nehmen und das XOR den Prozessor in einem Schritt machen lassen? Dann könntest du dir den ganzen itoa()-Wahnsinn sparen. Der ist nämlich echt völlig unnötig.
    🙂

    Meinst du in der Hamming Funktion ?
    Wenn ja habe ich das deshalb gemacht das ich die 1 aus dem XOR Produkt zählen kann.

    Als Bsp.: Wenn ich die Zahlen 1010 und 1111 als int übergeben würde und diese XOR Verknüpfe bekäme ich als Return ja ne 5 (Binär 101). Da wüsste ich jetzt nicht wie ich die 1 zählen kann. Dann müsste ich ja erst wieder die 5 in ne Dualzahl mittels ner Funktion umwandeln, diese in einem String speichern und dann die Anzahl von 1en Zählen.

    Deshalb dachte ich mir das ich die String umwandlung gleich am Anfang vornehme.

    Nur habe ich immer noch das Problem mit der führenden 0, die dann ja abgesägt wird.



  • µngbd schrieb:

    ausser man baut alles aus den Axiomen zusammen, aber das ist wiederum eine epische Laufzeitverschwendung

    es gibt eine programmiersprache, die mit 'axiomen' arbeitet? wie geht das? oder bedeutet der begriff da was anderes?

    µngbd schrieb:

    C++ hat sicher irgendeinen Zauberspruch, den man zwischen cin und die Variable schreiben muss, damit die Zahl zur Basis 17 genommen wird. Fragt dann wahrscheinlich insgeheim bei strtol() nach, weil Zaubern gar nicht so einfach ist, und deshalb von einem Magier geerbt werden muss.

    in c++ macht man sowas mit templates, dabei rechnet der compiler die werte für alle möglichen bitmuster eines 'unsigned' im voraus aus und speichert sie in einem 4GB array *fg*

    Chris12 schrieb:

    Leider darf ich keine andere Sprache als C nehmen. Da ich momentan im 1.Semester nur ANSI C behandele.

    C ist schon ok, für low-leveliges bitgewurschtel gibt es kaum besseres.

    Chris12 schrieb:

    Vielleicht hat ja der ein oder andere noch ein paar optimierungs tips.

    deine hammingdistanz-funktion sieht seltsam aus. wenn sie mit strings arbeiten soll (und es sieht so aus), dann hat das XOR dort doch nichts verloren. vorschlag (ungetestet):

    // geht davon aus, dass beide strings gleich lang sind
    int HammingDistance (char Code[],char Code2[])
    {
        int Hamming;
        for (Hamming=0; *Code; Code++, Code2++)
            if (*Code != *Code2)
                Hamming++;
        return Hamming;
    }
    

    Chris12 schrieb:

    Wenn ich 0100 eingeben wird an die Funktion 100 übergeben was mir auch logisch erscheint. Wie könnte ich die führende 0 erhalten

    bei der ausgabe z.b. kannste ja vorn nullen anhängen soviel du willst.
    🙂



  • fricky schrieb:

    deine hammingdistanz-funktion sieht seltsam aus. wenn sie mit strings arbeiten soll (und es sieht so aus), dann hat das XOR dort doch nichts verloren. vorschlag (ungetestet):

    // geht davon aus, dass beide strings gleich lang sind
    int HammingDistance (char Code[],char Code2[])
    {
        int Hamming;
        for (Hamming=0; *Code; Code++, Code2++)
            if (*Code != *Code2)
                Hamming++;
        return Hamming;
    }
    

    Wenn ich das richtig erkenne würde dann allerdings deine Funktion nur überprüfen ob die beiden Codewörter unterschidlich sind. Ich muss allerdings die enthaltenen 1 aus dem XOR Produkt der beiden Codwörter zählen.

    fricky schrieb:

    bei der ausgabe z.b. kannste ja vorn nullen anhängen soviel du willst.
    🙂

    Ich brauche die aber nicht bei der Ausgabe sondern bei der Übergabe an die Hamming Distance.

    Bsp.:

    0101
    1111
    ----
    1010 Hamming Distance von 2

    Da der Rechner aber die 0 abschneidet kommt das raus:
    101
    1111
    ----
    010 HD von 1



  • Ok hab gerade deine Funktion getestet, die funktioniert einwandfrei, ich verstehe allerdings nicht wieso.


Anmelden zum Antworten