wieder mal zahlensysteme...
-
hi leute,
hab folgendes problem: ich möchte einen dezimalwert in einen oktalwert umrechnen und diesen dann ausgeben lassen. die umrechnung funktioniert einwandfrei. da aber bei der berechnung der oktalwert "falschrum" gelesen werden muss, will ich den oktalwert als string "richtigrum" ausgeben. das funktioniert aber nicht:
#include <stdio.h> #include <limits.h> void main(void) { unsigned int dezimalzahl, zwischenwert, stelle=11; char oktal[12]; printf("Zahl: "); scanf("%d", &zwischenwert); if (zwischenwert >= 0 && zwischenwert <= UINT_MAX) { while (zwischenwert != 0) { dezimalzahl = zwischenwert; zwischenwert = zwischenwert / 8; dezimalzahl = dezimalzahl % 8; oktal[stelle] = dezimalzahl + '0'; stelle--; printf("%s", oktal); } } else printf("\nFalscher Zahlenwert! Der Wert muss positiv und ganzzahlig sein!\n"); }
kann mir jemand helfen?
danke im voraus
-
So würd's gehen aber das ist keine schöne Lösung
#include <stdio.h> #include <limits.h> void main(void) { unsigned int dezimalzahl, zwischenwert, stelle=11; char oktal[13]; oktal[12] = 0; printf("Zahl: "); scanf("%d", &zwischenwert); if (zwischenwert >= 0 && zwischenwert <= UINT_MAX) { while (zwischenwert != 0) { dezimalzahl = zwischenwert; zwischenwert = zwischenwert / 8; dezimalzahl = dezimalzahl % 8; oktal[stelle] = dezimalzahl + '0'; stelle--; } printf("%s\n", &oktal[stelle+1]); } else printf("\nFalscher Zahlenwert! Der Wert muss positiv und ganzzahlig sein!\n"); }
Kurt
-
danke für die antwort
aber was macht er da?oktal[12] = 0; ... printf("%s\n", &oktal[stelle+1]); ...
und du hast ihm ja 13 stellen zugewiesen, ich brauch aber nur 12, da UINT_MAX = FFFF FFFF und das im oktalsystem = 377 7777 7777 (also 11 stellen)
-
oktal[12] = 0; // string terminator ... printf("%s\n", &oktal[stelle+1]); // erstes Zeichen der oktalzahl ist das Zeichen an der stelle stelle +1 ...
Kurt
-
MastaZulu schrieb:
und du hast ihm ja 13 stellen zugewiesen, ich brauch aber nur 12, da UINT_MAX = FFFF FFFF und das im oktalsystem = 377 7777 7777 (also 11 stellen)
Das tut mir aber leid. hab mich verzählt.
KurtBTW hab übersehen dass du unsigned int verwendest. Dann brauchst du auch die Abfrage auf < 0 nicht.
-
ja des mit > 0 hab ich mir auch gedacht...
und danke nochmal!
-
noch eine frage:
was macht eigentlich der string terminator? und brauche ich den unbedingt?
gibts da alternativen dazu?
-
MastaZulu schrieb:
was macht eigentlich der string terminator? und brauche ich den unbedingt?
gibts da alternativen dazu?Auf diese Frage fällts schwer nicht zynisch zu antworten.
Also
string terminator : sagt den verschiedenen c-stringfunktionen dass der string jetzt zu ende ist.
Alternativen gibts keine nur altenative schreibweisen
z.boktal[12] = '\0';
Kurt
-
achso, '\0' kenn ich
nur fällt mir grad der name, unter dem es mir bekannt is, nicht ein...
also danke nochmal!
-
bin auf ein weiteres problem gestoßen:
den guten alten überlauf, obwohl ich zwischenwert <= UINT_MAX definiert hab, macht er trotzdem weiter...
-
Du machst ja auch kleiner-gleich. Wenn der auf gleich ist wird die Schleife wiederholt, weil der Zähler dann bereits wieder erhöht worden ist und auf 0 steht, was die Schleife bei dir auch weiterlaufen lässt. Wenn müsstest du >0 und/oder <UINT_MAX nehmen, damit die Abbruchbedingung korrekt funktioniert. Allerdings wird dann entweder für =0 oder für =UINT_MAX die Schleife nicht mehr durchlaufen. Eventuell solltest du ein Flag hinzufügen und das prüfen oder statt unsigned, signed Werte benutzen.
Edit: Ah verguckt, du prüft ja auf ungleich 0. Gehe mal davon aus, dass du || (ODER) statt && (UND) benutzt.
-
ich denk mal, ich bin noch zu blöd dafür... aber wenn ich < UINT_MAX mach oder >0 sowie <UINT_MAX kommt es trotzdem zum Überlauf und er führt es mit dem "überlaufenen wert" aus. vllt. hab ich auch nur wieder irgendwas aus leichtsinn vergessen. hier nochmal der Code:
#include <stdio.h> #include <limits.h> void main(void) { unsigned int dezimalzahl, ausgangswert, zwischenwert, stelle=10, pruefung; char oktal[12]; oktal[11]='\0'; printf("Geben Sie eine positive ganze Zahl ein: "); pruefung = (scanf("%d", &zwischenwert)); if (pruefung == 1) { if (zwischenwert < UINT_MAX) { ausgangswert = zwischenwert; while (zwischenwert != 0) { dezimalzahl = zwischenwert; zwischenwert = zwischenwert / 8; dezimalzahl = dezimalzahl % 8; oktal[stelle] = dezimalzahl + '0'; stelle--; } printf("\n%d entspricht im Oktalsystem der Zahl %s\n\n" ,ausgangswert, &oktal[stelle+1]); } else printf("Falsche Eingabe!\n"); } else printf("Falsche Eingabe!\n"); }
-
Hm, achso. Du gibst ne negative Zahl ein, dann erhältst du beim einlesen in einen unsigned Typ natürlich auch die repräsentation als unsigned Typ. Ich wüsste nicht das man das außer durch das einlesen in einen signed Typ irgendwie abfangen könnte.
-
habe ein weiteres problem:
bin gerade dabei, die "umkehrfunktion" zu programmieren, also oktal in dezimal....sieht bis jetzt folgendermaßen aus:
#include <stdio.h> #include <math.h> void main(void) { long dezimalzahl, zwischenwert=0; int stelle, exponent=11, pruefung; char oktal[12]; printf("Geben Sie eine Oktalzahl ein: "); scanf("%11s", &oktal); for (stelle = 10;stelle>=0;) { zwischenwert = zwischenwert + (oktal[stelle] - '0') * pow(8, exponent); printf("%ld , %s , %d\n", zwischenwert, oktal[stelle], exponent); stelle--; exponent--; } printf("%ld", zwischenwert); }
nun hab ich das problem, dass ich ja mal wieder von hinten nach vorne durchrechnen muss (hornerschema).
dazu bräuchte ich unter anderem, dass der komplette string vorher den wert 0 hat, da er mir sonst komische berechnungen durchführt.
wenn ich aber
char oktal[12]={0};
mache, stürzt das programm ab...
kann mir jemand helfen?
-
Du solltest etwas anders an die Sache rangehen - mit strlen kannst du die Länge deiner Eingabe (und damit auch die Position des letzten Zeichens bestimmen).
Außerdem habe ich das Horner-Schema so im Kopf, daß man damit von vorne durchrechnen kann (und ohne pow() auskommt):
zwert=0; for(stelle=0;octal[stelle];++stelle) zwert=8*zwert+(octal[stelle]-'0');
PS: Kleiner Hinweis: es heißt "int main(void)"
-
funktioniert einwandfrei, danke!
so, nun möchte ich noch eine Prüfung der Eingabe machen, d.h. das Programm soll nur ausgeführt werden, wenn der Benutzer Oktalzahlen eingegeben hat (0-7). Wenn Zahlen >7 oder Buchstaben vorkommen, soll er eine Fehlermeldung ausspucken.
ausserdem hab ich noch ein Problem was das Ergebnis betrifft. Wie zu sehen ist, gebe ich den ursprünglichen Oktalwert mit %o aus (was das ganze Programm natürlich um einiges vereinfacht hätte, aber es geht ja um die Rechnung). Wie kann ich ihn aber ohne %o, also als String ausgeben?#include <stdio.h> void main(void) { long dezimalzahl = 0; int stelle = 0; char oktal[12] = {0}; printf("Geben Sie eine Oktalzahl ein: "); scanf("%11s", &oktal); for (stelle = 0 ; oktal[stelle] ; ++stelle ) dezimalzahl = 8 * dezimalzahl + (oktal[stelle] - '0'); printf("\nDie oktale Zahl %o entspricht %ld im Dezimalsystem.\n\n", dezimalzahl, dezimalzahl); }
-
MastaZulu schrieb:
so, nun möchte ich noch eine Prüfung der Eingabe machen, d.h. das Programm soll nur ausgeführt werden, wenn der Benutzer Oktalzahlen eingegeben hat (0-7). Wenn Zahlen >7 oder Buchstaben vorkommen, soll er eine Fehlermeldung ausspucken.
Entweder du läufst vor der Rechnung einmal über den String und fragst ab, ob alles Oktalzahlen waren oder du fragst das in der Rechenschleife ab und verlässt die mit einem break, wenn ein falsches Zeichen kommt.
(oder drittens: Du liest ein mit "scanf("%11[0-7]",oktal);" - das bricht beim ersten Nicht-Oktal-Zeichen mit der Eingabe ab)
ausserdem hab ich noch ein Problem was das Ergebnis betrifft. Wie zu sehen ist, gebe ich den ursprünglichen Oktalwert mit %o aus (was das ganze Programm natürlich um einiges vereinfacht hätte, aber es geht ja um die Rechnung). Wie kann ich ihn aber ohne %o, also als String ausgeben?
Wieso nimmst du dort nicht deine Eingabe?
printf("Die Oktalzahl %s entspricht %d\n",oktal,dezimalzahl);
-
na weil oktal zuletzt nen anderen wert hat
halt, hab mich getäuscht, funzt, danke
EDIT:
hab jetzt das gesamte programm fertig... nun, nachdem ich alles zusammengefügt habe, steh ich mal wieder vor neuen alten problemen
hier mal das gesamte ergebnis:#include <stdio.h> #include <conio.h> #include <limits.h> void main(void) { long dezimalzahl, ausgangswert, zwischenwert; int auswahl, stelle, fehler = 0, schleife = 1, pruefung; char oktal[12]={0}; while (schleife == 1) { printf("*************Auswahl-Menue*************\n" "* *\n" "* 1) Konvertierung Dezimal -> Oktal *\n" "* 2) Konvertierung Oktal -> Dezimal *\n" "* 3) Abbruch *\n" "* *\n" "***************************************\n"); printf("Waehlen Sie: "); scanf("%d", &auswahl); if (auswahl == 1) { oktal[11]='\0'; stelle = 10; printf("Geben Sie eine positive ganze Zahl ein: "); pruefung = (scanf("%ld", &zwischenwert)); if (pruefung == 1) { if (zwischenwert >= 0 && zwischenwert <= LONG_MAX) { ausgangswert = zwischenwert; while (zwischenwert != 0) { dezimalzahl = zwischenwert; zwischenwert = zwischenwert / 8; dezimalzahl = dezimalzahl % 8; oktal[stelle] = dezimalzahl + '0'; stelle--; } printf("\n%ld dezimal entspricht im Oktalsystem der Zahl %s\n\n", ausgangswert, &oktal[stelle+1]); printf("\n\n\n\n\n\n\n\n\n"); } else printf("\nDie eingegebene Zahl ist zu gross!\n\n"); } else printf("\nSie haben Buchstaben eingegeben, geben Sie Zahlen ein!\n\n"); } else if (auswahl == 2) { oktal[12] = 0 ; stelle = 0; printf("Geben Sie eine Oktalzahl ein: "); scanf("%11s", &oktal); for (stelle = 0; oktal[stelle] ; ++stelle ) { if (oktal[stelle] >= '0' && oktal[stelle] <= '7') dezimalzahl = 8 * dezimalzahl + (oktal[stelle] - '0'); else fehler = 1; } if (fehler == 1) { printf("\nFehlerhafte Eingabe! Eine Oktalzahl besteht aus den Ziffern 0-7!\n"); printf("Wiederholen Sie die Eingabe\n\n\n\n\n\n\n\n\n\n\n"); } else printf("\nDie oktale Zahl %s entspricht %ld im Dezimalsystem.\n\n\n\n\n\n\n\n\n\n\n", oktal, dezimalzahl); } else if (auswahl == 3) schleife=0; else printf("\nFalsche Eingabe. Versuchen Sie es erneut.\n\n\n\n\n\n\n\n\n\n\n"); } }
so, folgendes funktioniert noch nicht / nicht mehr:
- unter (auswahl == 1) funktioniert die Überlauf-Prüfung nicht, d.h. auch bei zu hoch eingegebenen werten wird das programm ausgeführt.
- unter (auswahl == 2) kommt es wieder zu den seltsamsten ergebnissen... und am "oktal[12] = 0 ;" kanns nicht liegen, es funktioniert auch nicht, wenn ich das weglasse...
wieso denn nur... ich dreh bald durch
-
dezimalzahl ist nicht initialisiert.
Das solltest du unbedingt lesen
http://www.research.att.com/~bs/bs_faq2.html#void-main
KurtEDIT:
MastaZulu schrieb:
am "oktal[12] = 0 ;" kanns nicht liegen, es funktioniert auch nicht, wenn ich das weglasse...
Hat ach keinen Sinn. scanf() terminiert den string schon.
richtig wäre eigentlichscanf("%11s", oktal);