totty
Goto Top

Zeichenweise einlesen und in fortlaufender variable speichern

Ziel ist es ein Programm zu schreiben, welches Binäre Zahlen in Dezimal Zahlen umrechnet.
Dabei soll es egal sein, wieviele Nullen und Einsen man eingibt.
Wichtig ist, dass jedes Zeichen einzeln gelesen und gespeichert wird.

Ich habe da auch glatt eine Idee gehabt, leider endet diese in einer Endlos-Schleife.


#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv)
{
int a,b,c,erg,zahl;
a=0;
b=1;
c=0;
erg=0;
zahl=0;
char eingabe;
printf("Bitte geben Sie eine Binaere Zahl ein!");
scanf("%c",&eingabe);
while( eingabe !='#')
{
eingabe !=1
{ printf("\n\nSie haben keine Binaere Zahl eingegeben, bitte geben Sie erneut eine Binaere Zahl ein.\nKleiner Hinweis:\nEine Binaere Zahle besteht nur aus Nullen (0) > und Einsen (1).\nz.B.: 010110101\n");
}
else
{
("x%d",a) = eingabe;
a++;
}
}
while (a-b !=0)
{
a=a-b;
("x%d",a) = zahl;
erg = erg + zahl * 16^c;
c++;
b++;
}
printf("\nDas Ergebnis lautet:%d",erg);
fflush(stdin);
getchar();
}


Vielleicht sieht einer ja direkt mein Problem.

Gruß Totty

Content-ID: 153544

Url: https://administrator.de/contentid/153544

Ausgedruckt am: 20.11.2024 um 03:11 Uhr

Florian.Sauber
Florian.Sauber 21.10.2010 um 18:07:30 Uhr
Goto Top
Hi Totty,

Ich vershs nicht ganz!
Du willst, dass man eine Binärzahl eingibt und das programm einem die entsprechende Dualzahl ausgibt?
Eklär Doch mal, was Dein "Algorithmus" Deiner Meinung nach macht...

Und was meinst Du mit Endlosschleife? Dass die Abruchbedinngung nicht erfüllt werden kann?

LG Florian
76109
76109 21.10.2010 um 18:50:39 Uhr
Goto Top
Hallo Totty, Hallo Florian!

Mhm, die Sache mit der Endlosschleife ist anversicht klar, da ja nur ein einziges Zeichen (%c) vor (anstatt in) der While-Schleife eingelesen wirdface-wink

Ich würde Zahlenwerte (%d) einlesen, wobei ein einfacher Test mit "eingabe > 1" genügen sollte.

Mit C habe ich mich seit mehr als 15 Jahre nicht mehr beschäftigt. Von daher verstehe ich z.B. das hier
("x%d",a) = eingabe;
überhaupt nichtface-sad

Gruß Dieter
dog
dog 21.10.2010 um 21:23:30 Uhr
Goto Top
Von daher verstehe ich z.B. das hier

Das ist ja auch kein C, sondern Wünsch-dir-Was.


Und die Zahl 0 und der String "0" (den scanf immer liefern würde) sind in C ein großer Unterschied.

erg = erg + zahl * 16^c;

Und warum man 16 XOR c rechnen sollte weiß ich auch nicht.
^ ist nicht der Potenz-, sondern der Exklusiv-Oder-Operator in C.
Wertigkeiten berechnet man auch mit Potenz 2.

12345678
---------
10010101
#ist
1*2^7+
0*2^6+
0*2^5+
1*2^4+
0*2^3+
1*2^2+
0*2^1+
1*2^0
--------
     149

Zudem gibt es für n = n + x die Schreibweise n += x
Florian.Sauber
Florian.Sauber 21.10.2010 um 22:34:34 Uhr
Goto Top
Hallo nochmal,

Zitat von @76109:
Mhm, die Sache mit der Endlosschleife ist anversicht klar, da ja nur ein einziges Zeichen (%c) vor (anstatt in) der While-Schleife eingelesen wirdface-wink
Spielverderber face-wink
Mit C habe ich mich seit mehr als 15 Jahre nicht mehr beschäftigt. Von daher verstehe ich z.B. das hier
("x%d",a) = eingabe;
überhaupt nichtface-sad
Keine Angst, das versteht sicherlich nicht mal Dennis Ritchie und mich wundert auch, dass das der Compiler mitmacht.

Zitat von @dog:
Das ist ja auch kein C, sondern Wünsch-dir-Was.
LOL
Und die Zahl 0 und der String "0" (den scanf immer liefern würde) sind in C ein großer Unterschied.
scanf(%c,&eingabe); liefert schon einen Character an den Pointer, allerdings frage ich mich, wie er damit einen String 10101... einlesen will. Aber das ist echt das Geringste
Aber wie gesagt, mich wundert da so einiges. Daher hätte mich schon einmal zuerst interessier, wie er sich das vorstellt; was er annimmt, dass sein Code denn da macht...

Ich denke langsam verstanden zu haben, was seine Intention dabei war, ich würde es aber gern mal hören.

LG Florian
Totty
Totty 22.10.2010 um 08:49:36 Uhr
Goto Top
Zitat von @Florian.Sauber:

Du willst, dass man eine Binärzahl eingibt und das programm einem die entsprechende Dualzahl ausgibt?
Eklär Doch mal, was Dein "Algorithmus" Deiner Meinung nach macht...


Also, er soll nicht von Binär in Dual, sondern von Binär in Dezimal umrechnen.

Wichtig ist, dass das Programm jedes Zeichen einzeln einliest und in eine Variable speichert. Also keinen String einlesen.
Das soll das (x%d,a); a++; sein. Weiß nicht wie man sonst ein x1, x2, x3, x4, x5 etc. erstellen kann.
Sollte dann hinterher so sein wie x1 =1 x2=0 x3=1 x4=# wobei das #-Zeichen die eingabe beenden soll. Und anschließend soll er dann rückwärts rechnen.

also hier z.B. a=4
dann b=1 und a-b
damit der rückwärts die variablen verarbeitet.
x3 *2**0
x2 *2**1
x1 *2**2
Rechnet.
Die sich ergebende Zahl soll jeweils in zahl gespeichert werden und in erg = erg + zahl addiert werden.

Bis schließlich a-b = 0 und dann das erg ausgegeben werden soll.


Jetzt verständlicher? face-confused


Gruß Totty
Florian.Sauber
Florian.Sauber 22.10.2010 um 13:50:23 Uhr
Goto Top
Zitat von @Totty:
Zitat von @Florian.Sauber:

Du willst, dass man eine Binärzahl eingibt und das programm einem die entsprechende Dualzahl ausgibt?
Eklär Doch mal, was Dein "Algorithmus" Deiner Meinung nach macht...

Also, er soll nicht von Binär in Dual, sondern von Binär in Dezimal umrechnen.
Ähhm, das ist natürlich Quatsch. Hab ich mich verschrieben... Was ich meinte war Dualzahl in Dezimalzahl
Wichtig ist, dass das Programm jedes Zeichen einzeln einliest und in eine Variable speichert. Also keinen String einlesen. Das soll das (x%d,a); a++; sein. Weiß nicht wie man sonst ein x1, x2, x3, x4, x5 etc. erstellen kann. Sollte dann hinterher so sein wie x1 =1 x2=0 x3=1 ...
hab ich mir schon so gedacht. Aber dazu gibt es das sogenannte Array. ein String ist in C auch nicht anderes als eine "Art Array" aus charactern. Genauer gesagt ist es ein Pointer auf die Anfangsadressse diese "Arrays", daher auch immer *String (Asterisk * bei der Deklaration steht für Pointer und heisst dann Indirektionsoperator)
Und anschließend soll
er dann rückwärts rechnen.

also hier z.B. a=4
dann b=1 und a-b
damit der rückwärts die variablen verarbeitet.
x3 *2**0
x2 *2**1
x1 *2**2
Rechnet.
Und das machst Du am Anfang am besten mit einem Array. Mit einer Schleife holst Du quasi jeden einzelnen Integer ab und speicherst ihn in einem Arrayfeld.
Bsp.:
...
char a[5]; // Arraydeklaration für ein Feld mit
int i = 0; //Zähler für die Bestimmung des Arrayfeldes
while (i<5) {           // da Du verhindern musst, dass das Array überläuft, einlesen!
      a[i] = getchar();    // wäre wie scanf(%c, &a[i]); hier nur zur einf. Verdeutlichung
      i++;
}
printf("%s\n",a);  
Jetzt verständlicher? face-confused
Hoff ich Doch!

Viel Spass und LG
Florian

EDIT
Ach so, für "unbegrennzt lange" Eingaben ist es mit dem Array so ne Sache, aber da wirst Du dann was drüber lesen. Darauf und auf Arrays im Allg. an dieser Stelle einzugehen, würde den Rahmen sprengen. Gerade was Speicherallokation etc. angeht.
Eine Alternative wären dann Datenstrukturen wie die verkettet Liste.
Totty
Totty 22.10.2010 um 14:33:06 Uhr
Goto Top
Hey Florian,

danke für den Hinweis.
Mit dem Array, sollte es funktionieren. Denke selbst wann man das array auf 500 Stellen begrenzt sollte es als "unbegrenzt" gelten. Wer tippt schließlich mehr als 500 einsen und nullen? o_O

Werde das ganze mal einbauen und testen.

Gruß Totty
76109
76109 22.10.2010 um 14:33:52 Uhr
Goto Top
Hallo zusammen!

Also, vom Ansatz her könnte dieses Beispiel auch funktionieren, wobei ich mir bei einigen Definitionen wie z.B. "unsigned long integer" nicht mehr so ganz sicher bin. Eventuell geben ja Dog oder Florian noch ein paar Tip's dazu?

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv)
{
char Eingabe[80];

int i, s;

unsigned long integer Anzahl, Zahl, Ergebnis=0;

printf("Bitte geben Sie eine binäre Zahl ein: ");  

scanf("%s",&Eingabe);  // String einlesen  

Anzahl = StrLen(Eingabe) - 1;

// If (Anzahl > 31)  {...Fehlermeldung..., Return (1) }  Max 32 Bit

For (i=0, s=Anzahl;i<=Anzahl;i++, s--)
{
    Zahl = atol(Eingabe[i]);  // Ascii-Zeichen in Zahl konvertieren mit AtoL?
    
    if (Zahl & Not 1) {   // Zahl And 0xFFFFFFFE > 0 = Fehler
        printf("\n\nBitte nur binäre Zahlenwerte 0/1  (Dual-Basis 2) eingeben z.B. 10101...\n");  
        Return (1);
    }
    
    Ergebnis += zahl << s  
 // oder Ergebnis += zahl * 2^s, wobei's in C dafür glaube ich eine Funktion gibt? 
 // beim schieben gibt es möglicherweise bei Bit 31 einen Überlauffehler? 
}

printf("\nDas Ergebnis lautet:%ld",Ergebnis);  

Return (0);

Gruß Dieter
Totty
Totty 22.10.2010 um 16:02:55 Uhr
Goto Top
Hey Leute,

ich komme leider immernoch nicht ganz zum Ziel...

#include <stdio.h>
#define EOLN '#' 

int main(int argc, char *argv)
{
     
    
     printf("Bitte geben Sie eine Binaerzahl ein:");  
     
     int eingabe[500]; //Arraydeklaration 
     int i=0;           //Zähler
     
     while(eingabe[i]!= EOLN)
     {
                 i++; // Zähler erhöhen
                 eingabe[i] = getchar(); //Zeichen in Array speichern
                 
     
     }
     
     int c=1;
     int zahl=0;
     int rechnung=0;
     int erg=0;
     int potenz=0;
     int exp=0;
     
     
     while(i>0) // solange i größer null schleife
     {
             i=i-c; // i-c, damit die # nicht mitzählt
             zahl = eingabe[i]; // ergebnis stimmt
             exp = pow(2,potenz); // ergebnis stimmt
             rechnung = zahl * exp; // ergebnis stimmt
             erg = erg + rechnung; / ergebnis stimmt
             potenz++; //potenz erhöhen
      
/* AUSGABEN ZUM TESTEN BZW SUCHEN DES FEHLERS
      printf("i:%d\n",i); 
      printf("Eingabe:%d ,%d\n",eingabe[i],zahl);  
      printf("Exponent:%d\n",exp);  
      printf("Rechnung:%d\n",rechnung);           
      printf("Ergebnis:%d\n",erg); 
*/
               
     }
     printf("\n\nIhr Ergebnis lautet:%d",erg);  
     fflush(stdin);
     getchar();
}

Leider ist es im Moment so, dass der letzte eingelesene Wert immer aus der Reihe tanzt. Kann mir nur nicht erklären, warum das so ist. Vielleicht weiß einer von euch Rat?


Vielen DANK

Gruß Totty
Totty
Totty 22.10.2010 um 16:10:52 Uhr
Goto Top
Habe meinen Fehler gerade gefunden -.-

#include <stdio.h>
#define EOLN '#' 

int main(int argc, char *argv)
{
     
     
     printf("Bitte geben Sie eine Binaerzahl ein:");  
     
     int eingabe[500]; //Arraydeklaration 
     int i=0;           //Zähler
     
     while(eingabe[i]!= EOLN)
     {
                 i++;
                 eingabe[i] = getchar();
                 
     
     }
     
     int c=1;
     int zahl=0;
     int rechnung=0;
     int erg=0;
     int potenz=0;
     int exp=0;
   
     
     while(i>1)
     {
             i=i-c;
             zahl = eingabe[i] - '0';  
             exp = pow(2,potenz);
             rechnung = zahl * exp;
             erg = erg + rechnung;
             potenz++;
      printf("i:%d\n",i);  
      printf("Eingabe:%d ,%d\n",eingabe[i],zahl);  
      printf("Exponent:%d\n",exp);   
      printf("Rechnung:%d\n",rechnung);            
      printf("Ergebnis:%d\n",erg);  
               
     }
     printf("\n\nIhr Ergebnis lautet:%d",erg);  
     fflush(stdin);
     getchar();
}

Danke nochmals für Eure Hilfe!!!!


Gruß Totty
Florian.Sauber
Florian.Sauber 22.10.2010 um 17:32:43 Uhr
Goto Top
Hi nochmal,

Colle Sache, da bist Du doch in kurzer Zeit schon weit gekommen. Da lässt natürlich noch einiges optimieren, aber wenn Du das selbst so hinbekommen hast, bist Du auf nem guten Weg

Ein anderer Ansatz wäre, das Hornerschema heranzuehmen, solange die Binärzahl mehr als 3 Ziffer lang ist.
So kann man "vorwärtsgerichtet" rechnen und spart sich die Potenzen.

Als Erklärung:
Ich kümmer mich mal nicht um Abbruchbedingungen überlaufende Variablen und Typenumwandlung...
Binärfolge nehm ich mal das Beispiel von dog oben: 10010101
int eingabe = (1,0,0,1,0,1,0,1);
int i , erg;
for (i=0; erg=0, i<8, i++) erg=erg*2+a[i]; //*2 wegen Dualsystem
0: erg = 0 * 2 + 1 = 1
1: erg = 1 * 2 + 0 = 2
2: erg = 2 * 2 + 0 = 4
3: erg = 4 * 2 + 1 = 9
4: erg = 9 * 2 + 0 = 18
5: erg =18 * 2 + 1 = 37
6: erg = 37 * 2 + 0 = 74
7: erg = 74 * 2 + 1 = 149


LG Florian
Totty
Totty 22.10.2010 um 19:13:32 Uhr
Goto Top
Hey Florian,

ja, das ganze hat mich heute 1 1/2 Stunden gekostet, aber es hat sich gelohnt.

Deine Möglichkeit könnte man auch noch einbauen.
Am Anfang eine kurze Auswahl, welchen Weg man wählen möchte.
Der Anwender wird davon zwar nichts mitbekommen, aber man hätte beide Möglichkeiten im Programm.

Habe vorhin auch noch ein wenig weiter gespielt, und eine Abfrage des eingegebenen Strings erstellt, ob nur 0,1, und # verwendet wurden, ansonsten springt das Programm an den Anfang zurück.
Ebenso, ob man am Ende noch eine Zahl berechnen will, oder es direkt beenden will.

Mit ein wenig Spaß und konzentration an der Sache, lässt sich schon einiges machen!


Gruß Totty
Florian.Sauber
Florian.Sauber 22.10.2010 um 23:29:15 Uhr
Goto Top
Hi Totty,

ich habs eigentlich nur geschrieben, damit man sieht, dass es mehr und effektivere Verfahren als die klassische Variante gibt.
Ich würde darauf verzichten, dass zusätzlich einzubauen.
Mehr bring Dir sicherlich die Umrechnung in andere Zahlensysteme und zurück.
Das kannst Du auch mit schönen Abfragen gestalten
Ausgangs-Zahlensystem wählen
(1) Dualsystem
(2) Oktalsystem
<EINGABE>
Ziel-Zahlensystem wählen
Dafür Prüfmechanismen entwickeln
Sie haben Oktalsystem gewähl, verwenden aber die Ziffer 9...

Dazu am besten mal einlesen, wie man Funktionen auslagert und Parameter oder Rückgabewerte übergibt, um es besser Strukturieren zu können.

Schleifen umzuwandeln (for in while,...) oder Verschachtelte Schleifen sind auch gängige Übungen. Dazu kann man z.B üben, Zahlenreihen zu sortieren (einfache/elementare Sortieralgorithmen wären z.B. Insertion-Sort, Bubble-Sort, Quicksort etc.) und weiter mit Arrays rumzuspielen, auch mehrdimensionalen.
Unbedingt notwendig (in C) ist der sichere Umgang mit den verschiedenen Datentypen und dem Umwandeln oder das Thema Speicherverwaltung. Auch kommt man in C ohne Pointer nicht allzu weit. Dazu kannst Du z.B. üben ein Array über Speicheradressen auszulesen, um Dich so gleichzeitig mit der Speicherverwaltung vertraut zu machen.

Ein Adress- und Telefonverzeichnis ist eine nette Übung für Datenstrukturen und wappnen Dich für das Thema dynamische Datenstrukturen.

Danach kann man sich dann in die wunderbare Welt der Rekursion einzusteigen und sich mit gängigen Algorithmen vertaut zu machen.
Um auch über das beenden des Programms etwas mit den Daten anzufangen die E/A-Fuktionen und Du bist einigermassen sicher für das Thema Bibliotheken.

Ausserdem würde ich Dir, nachdem Du etwas Sicherheit gewonnen hast, unbedingt anraten frühzeitig auf auf Objektorientierung umzusteigen. Da Du mit C angefangen hast, bietet sich hier natürlich C++ an, wobei viele gleich zu Java tendieren. Ich habe einige Leute gesehen, die haben eine ganze Weile prozedual programmiert und hatten dann extreme Schwierigkeiten mit OOP. Aber ist sicherlich abhängig vom Typ.

Auch wenn das viele anders sehen, finde ich C keine schlechte Sprache um sich mit dem Thema Programmieren zu beschäftigen. Das schlimmste, was Dir passieren kann ist, dass Du Dich später wunderst, wie einfach das woanders gehtface-wink

Mit ein wenig Spaß und konzentration an der Sache, lässt sich schon einiges machen!
Ist die beste Voraussetzungface-smile

Viel Spass und Erfolg
Florian

PS.:
Wenn Du Dich etwas ernsthafter mit dem Thema beschäftigen und bei C bleiben willst, leg Dir unbedingt eine gute Referenz zu. Ich persönlich seh das altmodisch, und hab es in schriftlicher Form im Bücherregal / auf dem Schreibtisch.
Eine gute Referenz erspart dir viel Zeit und Zähneknirschen...
Nicht nur als Referenz rate ich zu DEM Standardwerk von Kernighan & Ritchie
Biber
Biber 23.10.2010 um 10:06:34 Uhr
Goto Top
Moin Totty,

nur ergänzend zu Florian.Sauber

Zitat von @Florian.Sauber:
PS.:
Wenn Du Dich etwas ernsthafter mit dem Thema beschäftigen und bei C bleiben willst, leg Dir unbedingt eine gute Referenz zu.
Ich persönlich seh das altmodisch, und hab es in schriftlicher Form im Bücherregal / auf dem Schreibtisch.
Eine gute Referenz erspart dir viel Zeit und Zähneknirschen...
Nicht nur als Referenz rate ich zu DEM Standardwerk von Kernighan & Ritchie

-> Bitte lies (bzw. überfliege) zu diesem Buch auch die Rezensionen, die ziemlich einheitlich sagen:
..." Hervorragendes Buch, grauenhafte Übersetzung"
"Wer mehr als drei Worte Englisch kann, kaufe die Originalausgabe!"

Gerade Referenzhandbücher im IT-Umfeld können einem oft nur mit stilistischen und didaktischen Defiziten den Spass an vielem verleiden.

Grüße
Biber
Florian.Sauber
Florian.Sauber 23.10.2010 um 16:30:47 Uhr
Goto Top
Da hat Mr. Biber natürlich vollkommen recht!
Kommt davon, wenn man schnell mal das erste Google-Ergebnis kopiert und nicht aufpasst...

LG Florian
Mehr von TottyTottyIPSec VPN Tunnel steht, aber kein Ping möglichTotty - 6 KommentareTottySwitche mit Glasfaserverbinden - minimal AbstandTotty - 13 KommentareTottyRechner hängt bei isapnp.sysTotty - 4 KommentareTottyDoppelte Werte aus SQL Datenbank löschenTotty - 3 Kommentare
Heiß diskutiert
FohnbitNetzwerkgerät im Netzwerk verschwindet nach NeustartFohnbit - 34 KommentarecseLaufwege erfassen in großer Hallecse - 20 Kommentaresuperfun2k24SSL VPN an Sophos UTM sehr langsamsuperfun2k24 - 16 Kommentareprplemk2Testumgebung bauen (Grundlegend)prplemk2 - 15 KommentareFrontierAbsicherung eines privaten GastnetzesFrontier - 14 KommentareadmtechEntwicklertagebuch: Release 6.4 - Filteradmtech - 13 KommentareaufdemmarsHP Z620 USB hat kein Strom beim Startenaufdemmars - 13 Kommentareuser217Kaufberatung Hardware - Hyper-V Cluster 3 Nodesuser217 - 12 KommentareYan2021Nachricht an mehrere PCs im Netzwerk sendenYan2021 - 12 KommentareManuManu2021Verpasster Anruf von +49-030-123456 mit einer Mobilfunk Prepaid SIMManuManu2021 - 11 KommentareMegaadwwhWireguard tunnel kann nicht hergestellt werdenMegaadwwh - 11 KommentareZZaaiiggaaEDIFACT - Keins vorhanden ?ZZaaiiggaa - 11 Kommentare