Mit "Sscanf" String auf Int durchsuchen
-
fflush(stdin)
wird ja meist gemacht um Falscheingaben abzufangen, oder weil der Programmierer nicht weiß, wie manscanf
nutzt.scanf
ist allerdings auch eine Monsterfunktion, die auch Zeit zur Auswertung benötigt.
In dem Beispiel von Youka hätte ich darumstrtol
stattsscanf
genommen.
-
Gehört jetzt nicht zum Thema, wollte nur keinen neuen Thread anfangen, weil nicht soo wichtig:
Gibt es eine möglichkeit Zahlen binär darstellen zu lassen?
Quasi Input: 25 Dezimal
Output(32Bit Breite) : 11001 Binär??
Also "fertige" Funktion wäre toll. Wenn nicht..... ich hab grad nicht wirklich eine Idee wie ich das am einfachsten Umsetzen könnte....
-
beginner_offl schrieb:
Gibt es eine möglichkeit Zahlen binär darstellen zu lassen?
Klar
beginner_offl schrieb:
Also "fertige" Funktion wäre toll.
In der Standardbibliothek gibt es keine Funktion.
Du kannst ja mal nach der Funktion itoa suchen. Bei deinem Compiler oder den Quellcode der Funktion.
Es gibt allerdings auch eine Version mit fester Basis 10.beginner_offl schrieb:
Wenn nicht..... ich hab grad nicht wirklich eine Idee wie ich das am einfachsten Umsetzen könnte....
Kennst du dich mit den binären Operatoren (& | >> <<) aus?
Es geht auch mit % und /Wo soll die Darstellung hin? In einen String oder Bildschirm/Datei?
-
Kennst du dich mit den binären Operatoren (& | >> <<) aus?
Jein... Also ich bekomms meistens schon hin ... mit etwas einlesen und so, aber ich werd nicht wirklich warm mit UND Wort Verknüpfungen.
Es geht auch mit % und /
... Das wäre mein Favorit gewesen. So wie man es hald "händisch" ausrechnet.
Durch 2 teilen, Rest, usw usw.Wo soll die Darstellung hin? In einen String oder Bildschirm/Datei?
Wie kann ich die Darstellung überhaupt realisieren? Also Bildschirm evtl. mit printf("%x", ...)
Als String wäre natürlich auch nicht schlecht.Also ich bin ein bisschen "geschockt", das es in C keine Stan-Funktion gibt für sowas... Bin da evtl. berufl. etwas verwöhnt, aber da kann ich in jeder Sprache egal welchen Speicherbereich, bzw. Wert mit einen Klick in Binär darstellen lassen. (Steuerworte, Zustandsworte->einzlne Bits auswerten....).
-
Richtige Programmierer, für die ist C gemacht, können die Bits auch in Oktal- und Hex-Darstellung sehen.
Bei der Ausgabe auf den Bildschirm/Datei wäre
putchar('0');
bzwputchar('1');
angebracht.
Mit printf ist da nix.Es sei denn du baust dein eigenes itoa. Da wird das ergebniss als String abgelegt.
Da kannst du dannprintf("%s", itoa(x,str,2));
machen. (oder ein itoa2, das nur in Dualzahlen wandelt)Eine Möglichkeit:
Du hast eine Bitmaske, in der nur ein Bit gesetzt ist. Am Besten das MSB, da dies ja zuerst ausgegeben werden soll.Diese Maske verundest du mit deinem Wert. An der Stelle, wo beide Zahlen das geliche Bit gesetzt haben, bleibt diese Bit auch gesetzt.
10100101 Wert
10000000 Maske
-------- &
10000000 Ergebnis ist ungleich 0 -> Bit ist 1. '1' ausgeben oder im String speichernDann wird die Maske um eine Stelle nach rechts verschoben und der Vorgang wiederholt
10100101 Wert
01000000 Maske
-------- &
00000000 Ergebnis ist 0 -> Bit ist 0. '0' ausgeben oder im String speichernWieder eine Stelle verschiebn, verunden, ... usw, bis die Maske 0 ist.
Das ganze bitte mit unsigned Werten, denn nur da ist garantiert, das beim rechtsschieben auch eine 0 vorne eingschoben wird.
-
10100101 Wert
10000000 Maske
-------- &
10000000 Ergebnis ist ungleich 0 -> Bit ist 1. '1' ausgeben oder im String speichernDann wird die Maske um eine Stelle nach rechts verschoben und der Vorgang wiederholt
10100101 Wert
01000000 Maske
-------- &
00000000 Ergebnis ist 0 -> Bit ist 0. '0' ausgeben oder im String speichernDas werd ich mal ausprobieren.
Dann sehen wir weiter. Evtl. lass ich dann die %=2 bzw. /=2 Sache bleiben......
-
Nachtrag... Mir ist noch was eingefallen. Für meinen Ursprünlichen Gedanken, also mit % und / ... da wollte ich auch gleich mit putchar ausgeben...
Geht ja nicht, müsste das "Ergbnis" ja erst drehen...
Gibt´s nen ROL befehl?5%2 != 0 ? putchar("1") : putchar("0")
....
Weißt du wie ich meine?
-
Habs jetzt mal "my-Way" gemacht...also die "Teilen" Variante.
Ist noch nicht ganz fertig, funktioniert aber erstmal.
#include <stdio.h> #include <stdlib.h> #define _MEM (sizeof(int)*8) #define LSB (sizeof(int)*8-1) #define HIGH '1' #define LOW '0' void tobin(void){ char bin[_MEM], *show; int init, i,j, erg; bin[_MEM]='\0'; for(init=0; init<_MEM; init++) bin[init]='0'; i=2569; j=0; do{ if ((i%2)!=0){ puts("Rest"); printf("i : %d\n", i); bin[LSB-j]=HIGH; j++; i/=2; printf("i : %d\n", i); } else{ puts("kein Rest"); bin[LSB-j]=LOW; j++; i/=2; } system("pause"); }while (i!=0); j--; show=&bin[LSB-j]; puts(show); }
Die Puts("rest")... und system("Pause") sind / waren nur zum Beobachten.
Jetzt muss ich dann noch das Ergebnis zurückgeben und uint verwenden.
Kann man den Rest so lassen?Die Variante mit >> << & | ist glaub ich eleganter, mit der setzte ich mich noch auseinander :p
-
Wie war das bei Arrays?
// Wenn du ein Array hast char bin[_MEM]; // dann hat das _MEM Elemente. // bezeichnet von 0 bis _MEM-1 bin[_MEM]='\0'; // Das Element mit dem Index _MEM gibt es nicht !!!
Alles was im if- und else-Zweig gleich ist, kannst du raus ziehen
do { if ((i%2)!=0) { // kann nur 1 sein bin[LSB-j]=HIGH; } else { bin[LSB-j]=LOW; } j++; i/=2; } while (i!=0);
Was bleibt ist dann
do { bin[LSB-j]=(i%2)+'0'; j++; // Das könnte sogar noch bei bin[LSB-j++] stehen i/=2; } while (i!=0);
-
Und wenn du die 2 durch eine Variable ersetzt, kannst du so schon mal Zahlen bis zur Basis 10 anzeigen.
Für andere Basen (bis 36) geht das so:
static const char ziffern = "01234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ"; do { bin[LSB-j]=ziffern[i%basis] j++; i/=basis; } while (i!=0);
-
Wie war das bei Arrays?
...Shit, ich sollte nichts tippen oder veröffentlichen, wenn ich schon ein paar Bier getrunken habe.
Mann ist das peinlich. Das sollte eigentlich nicht passierenDIe verkürzungen, bzw. was raus kann /muss hab ich jetzt noch gemacht.
Auch die String Rückgabe. (Dazu noch die Frage : Ist gängig so oder? Also nen String zurück geben, wird schon meist so gemacht oder? Der Aufrufer kümmert sich um den Speicher, nicht die Funition?)Hier der Code:
#include <stdio.h> #include <stdlib.h> #include <string.h> #define _MEM ((sizeof(int)*8)+1) #define LSB ((sizeof(int)*8)-1) #define HIGH '1' #define LOW '0' char* tobin(char *str, unsigned int value){ char bin[_MEM], *show; int init, j=0, erg; bin[_MEM-1]='\0'; for(init=0; init<_MEM-1; init++) // ich hab inits gern :-) bin[init]='0'; do{ if ((value%2)!=0){ bin[LSB-j]=HIGH; } else{ bin[LSB-j]=LOW; } j++; value/=2; }while (value!=0); show=&bin[LSB-(--j)]; strcpy(str, show); return (str); }
Ich habe jetzt bewusst nicht weiter verkürzt, mir ist :
do { bin[LSB-j]=(i%2)+'0'; j++; // Das könnte sogar noch bei bin[LSB-j++] stehen i/=2; } while (i!=0);
klar, aber ich kann den obrigen Code in 2 Jahren auch noch ohne "nachdenken" lesen. Generell... mich persönlich stören ein paar Zeilen mehr nicht sooo, wenn ich mich später mal leichter mit lesen tu.
-
beginner88888 schrieb:
Auch die String Rückgabe. (Dazu noch die Frage : Ist gängig so oder? Also nen String zurück geben, wird schon meist so gemacht oder? Der Aufrufer kümmert sich um den Speicher, nicht die Funition?)
Ja.
Einfacher wäre
#define _MEM ((sizeof(int)*8) char bin[_MEM+1]; // und nur bei der Definition Einen mehr.
Du kannst auch gleich auf str arbeiten, dann brauchst du bin nicht. (evtl musst du den String zum Schluss umdrehen)
return ist keine Funktion, daher braucst du die Klammern nicht.
beginner88888 schrieb:
aber ich kann den obrigen Code in 2 Jahren auch noch ohne "nachdenken" lesen.
Da ist
show=&bin[LSB-(--j)];
aber schwieriger zu verstehen alsbin[LSB-j]=(i%2)+'0';
Wobei das größte Problem dabei das LSB-j ist.
-
evtl musst du den String zum Schluss umdrehen
hmm... gibt´s da was fertiges oder muss ich das selbst basteln?
-
beginner_oofl schrieb:
hmm... gibt´s da was fertiges oder muss ich das selbst basteln?
Schau mal in der string.h
Ich würde die Funktion strrev nennen.
Wenn du nichts findest, musst du es selber machen. Ist aber nicht schwer, da du das Ende vom String schon hast.
Da hast du ja eine '0' oder '1' abgelegt.
-
Werde morgen die "Shift" Variante probieren.
Frage vorab, passt die "Maske" so?
#include <stdio.h> #include <stdlib.h> #define _MEM sizeof(int)*8 void shift(void){ int mask; unsigned int value; mask= 0x1; mask<<=_MEM-1;
Wenn ich das MSB "setzen" will , wäre das ja 0x80000000
Also müsste das mit sizeof(int) ja passen?OFF Topic: eine potenzier funktion für INT hab ich auch nicht wirklich gefunden. Hab schon mal eine selber gemacht, aber etwas wie value= 2^5 geht nicht oder?
-
mask sollte auch unsigned sein.
Deine Variante geht. Oder als Einzeilermask = 1 << _MEM-1;
beginner88888 schrieb:
aber etwas wie value= 2^5 geht nicht oder?
Doch, klar.
Aber dafür braucht es keine Funktion. Du machst das da oben doch schon.
Überleg mal, was ein links-Shift bedeutet. (Fang mit der 1 an und schiebe um eine Stelle)
-
Arr.... Wie war das mit dem Wald und den Bäumen...
Klar, SHLAber etwas wie 5^7 krieg ich mit Shiften nicht hin...
-
Ich hab jetzt 2 Varianten mit der Rückgabe gemacht.
Eine arbeitet direkt auf dem "Übergebenen" String, die andere nutzt nen "lokalen" String.Wie wäre das favorisierte Vorgehen? Bin ziemlich unschlüssig, irgendwie gefällt mir keine der beiden Farianten.
V1:
char* sh_bin(unsigned int value, char *str){ unsigned int mask; char *show=NULL, *buffer=str; int erg=0 ; mask=0x1; // => LSB is set mask<<=_BITS-1; printf("Value in Dez : %u\n", value); str[_BITS]='\0'; while (mask !=0){ if ((erg=value&mask)==0){ *str='0'; } else{ *str='1'; if (show == NULL){ show=str; } } str++; erg==0 ? putchar('0') : putchar('1'); mask>>=1; } *str='\0' ; puts("\nValue in BIN 'cleared':"); puts(show); str=buffer; // set pointer back to starting adress strcpy(str, show); return str; }//END
V2:
#include <stdio.h> #include <stdlib.h> #include <string.h> #define _BITS sizeof(int)*8 char* to_bin4(unsigned int value, char* string){ unsigned int mask ; unsigned int convert; char str[_BITS+1], *show=NULL; int erg=0, i=0 ; str[_BITS]='\0'; mask=0x1; // => LSB is set mask<<=_BITS-1; printf("Value in Dez : %u\n", value); while (mask !=0){ if ((erg=value&mask)==0){ str[i]='0'; } else{ str[i]='1'; if (show == NULL){ show=&str[i]; } } i++; erg==0 ? putchar('0') : putchar('1'); mask>>=1; } puts("\nNow in Binary:\n"); puts(str); puts(show); // Starts with "Leading" '1'; strcpy(string, show); return string ; }
Es gab auch noch ne 3. Variante, ähnlich der ersten, die direkt auf dem Übergebenen String , aber mit index arbeitet.
Hmm....
-
Noch was... Wie würdet Ihr die "Rückwandlung" von dem String (10010 z.b.) in Dezimal machen?
Habs jetzt mal mit " strtoul(string, NULL, 2) " gelöst...
Dachte daran es selbst zu machen mit einer Maske wo jede Stelle Ihrem Wert zugedacht ist...
-
Sind die beiden Varianten soo schlecht??