C++ Funktion um Text in Binärcode zu übersetzen gibt unerwartete Rückgabewerte.
-
Hallo,
Ich lerne jetzt seid knapp einem Monat C++, habe auch schon kleinere Programme fertig bekommen und hatte nun die Idee eine Konsolenanwendung zu schreiben, die Text in binärcode übersetzt. Da ich sowieso etwas zum Thema Funktionen bzw Header-Files machen wollte erschien mir das gleich passend.
Das Problem ist das mir die Funktion binary einen mir unerklärlichen Rückgabewert liefert !.
**
System: Ubuntu 14.04 LTS
Entwicklungsumgebung Eclipse
**
Hier ist nun der Code:
Main:string text; int stringmarke=0; cout << "Bitte gib nun den Text ein!" << endl; cin >> text; while(text[stringmarke] != 0) { cout << binary(text[stringmarke]); cout << "\n" << endl; stringmarke++; }
Header-File:
#ifndef HEADER_H_ #define HEADER_H_ int binary(char); #endif /* HEADER_H_ */
Sourcefile in dem die funktion liegt! :
#include "Header.h" int binary(char text) { long int binary; switch(text) { case '@': { binary =01000000; break; } case 'A': { binary =01000001; break; } case 'B': { binary =01000010; break; } case 'C': { binary =01000011; break; } case 'D': { binary =01000100; break; } case 'E': { binary =01000101; break; } case 'F': { binary =01000110; break; } case 'G': { binary =01000111; break; } case 'H': { binary =01001000; break; } case 'I': { binary =01001001; break; } case 'J': { binary =01001010; break; } case 'K': { binary =01001011; break; } case 'L': { binary =01001100; break; } case 'M': { binary =01001101; break; } case 'N': { binary =01001110; break; } case 'O': { binary =01001111; break; } case 'P': { binary =01010000; break; } case 'Q': { binary =01010001; break; } case 'R': { binary =01010010; break; } case 'S': { binary =01010011; break; } case 'T': { binary =01010100; break; } case 'U': { binary =01010101; break; } case 'V': { binary =01010110; break; } case 'W': { binary =01010111; break; } case 'X': { binary =01011000; break; } case 'Y': { binary =01011001; break; } case 'Z': { binary =01011010; break; } case 'a': { binary =01100001; break; } case 'b': { binary =01100010; break; } case 'c': { binary =01100011; break; } case 'd': { binary =01100100; break; } case 'e': { binary =01100101; break; } case 'f': { binary =01100110; break; } case 'g': { binary =01100111; break; } case 'h': { binary =01101000; break; } case 'i': { binary =01101001; break; } case 'j': { binary =01101010; break; } case 'k': { binary =01101011; break; } case 'l': { binary =01101100; break; } case 'm': { binary =01101101; break; } case 'n': { binary =01101110; break; } case 'o': { binary =01101111; break; } case 'p': { binary =01110000; break; } case 'q': { binary =01110001; break; } case 'r': { binary =01110010; break; } case 's': { binary =01110011; break; } case 't': { binary =01110100; break; } case 'u': { binary =01110101; break; } case 'v': { binary =01110110; break; } case 'w': { binary =01110111; break; } case 'x': { binary =01111000; break; } case 'y': { binary =01111001; break; } case 'z': { binary =01111010; break; } } return binary; }
Ein String besteht ja aus Chars die man einzeln ja auch mit string[1] aufrufen kann, (soweit ich weiß).Nun wollte ich die Chars des Strings nacheinander an die Funktion übergeben doch der Rückgabewert hat nichts mit der switch schleife in der Funktion zu tun. Ändere ich den Binärwert in der Funktion hat dies auch keinen Einfluss auf den Rückgabewert. Ich währe euch sehr dankbar wenn ihr mir helfen könntet und wenn es geht , auf mein Lösungsansatz eingehen könntet, da ich es selbst gerne können würde und nicht nur Code kopieren möchte
. Ich bin aber für jede Lösung sehr Dankbar!
Wenn ich auf Build all klicke kommt auch kein Error oder Warnung wenn ich dann allerdings in die Konsole schaue sehe ich das :
5:03:38 **** Incremental Build of configuration Debug for project Test **** make all Building file: ../src/Test.cpp Invoking: Cross G++ Compiler g++ -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/Test.d" -MT"src/Test.d" -o "src/Test.o" "../src/Test.cpp" ../src/Test.cpp: In function ‘int main()’: ../src/Test.cpp:27:32: error: invalid types ‘char[int]’ for array subscript cout << binary(text[position]); ^ make: *** [src/Test.o] Error 1 15:03:39 Build Finished (took 1s.22ms)
Gruß Tim !
-
Hier liegt vermutlich wieder (wäre das Thema nicht mal was für die FAQ?) eine Fehlinformation darüber vor wie überhaupt Zahlen im Computer gespeichert werden. Wenn du ein
int
oderchar
hast (ja auchchar
sind am Ende nur Zahlen) dann sind diese IMMER binär im PC gespeichert. Das bei der Ausgabe eine Zahl in der Dezimaldarstellung auftaucht oder bei einemchar
das entsprechende Zeichen wird erst bei der Ausgabe entschieden. Eine Möglichkeit binär Zeug auszugeben ist z.B. über diebitset
Klasse. Damit sähe dein Programm dann wie folgt aus:#include <iostream> #include <string> #include <bitset> using namespace std; int main() { string text; int stringmarke = 0; cout << "Bitte gib nun den Text ein!" << endl; cin >> text; while (text[stringmarke] != 0) { cout << bitset<8>(text[stringmarke]) << endl; stringmarke++; } }
Oder wenn du es selbst machen möchtest dann sollte deine Funktion ein
string
statt einemint
zurück geben. Und dann solltest du auch kein riesenswitch
bauen sondern dir einen allgemeinen Algorithmus dazu überlegen. Im übrigen sind Zahlen die mit 0 beginnen keine binären Zahlen sondern Zahlen zur Basis 8! Daher kriegst du auch wohl deine komische Ausgabe. Wenn man binäre Zahlen eingeben möchte dann geht das mit0b
am Anfang (also0b01000000
beispielsweise).
-
Wenn das keine Fehlermeldung ist, was dann?
Der Code in der Fehlermeldung passt nicht zu dem hier gezeigten.01001 ist eine Oktalzahl.
Deine Vorstellung von char scheint auch falsch zu sein: die Werte sind natürlich schon binär.
-
Außerdem mischst du strings und c-strings (nullterminierte chararrays). Die Prüfung auf nicht-null in der Schleife ist falsch, es muss in etwa so aussehen:
for(int i = 0; i < text.size(); ++i) { // mach was mit text[i] }
-
01001 ist eine Oktalzahl.
weil mit 0 beginnend, bei C++14 geht auch 0b01001
-
Hallo Hyde++,
Hyde++ schrieb:
Außerdem mischst du strings und c-strings (nullterminierte chararrays). Die Prüfung auf nicht-null in der Schleife ist falsch, es muss in etwa so aussehen:
for(int i = 0; i < text.size(); ++i) { // mach was mit text[i] }
Also das dieser Code sicherlich schöner aussieht ja, aber warum ist es falsch in C++ auf eine Null-Terminierung zu prüfen?
int main() { std::string s("hello"); bool r = s[s.size()] == '\0'; // True bool ptr = &s[0] == s.c_str(); // True return 0; }
Soweit ich das bei der STL von MS VS 2013 sehe, ist der Datenpointer von '&string.at(0)' und 'string.c_str()' identisch.
Viele Grüße
Jakob
-
Es ist nicht richtig falsch aber
std::string
kann auch Strings mit Null Terminator drin speichern. Wenn man also nur bis zum ersten Null Terminator ließt hat man eventuell nicht den ganzen String verarbeitet.
-
So wie es im Ursprungspost steht ist es richtig falsch, da auf einen Index ausserhalb des gültigen Wertebereichs zugegriffen wird.
-
manni66 schrieb:
So wie es im Ursprungspost steht ist es richtig falsch, da auf einen Index ausserhalb des gültigen Wertebereichs zugegriffen wird.
Wo? Der
operator[]
erlaubt auch den Zugriff auf den Null Terminator.
-
Aber nicht auf den Index size(), denn sonst würde at() ja auch damit funktionieren
string s("Test"); cout << s.at(s.size()) << '\n'; // <- out_of_range exception
-
Th69 schrieb:
Aber nicht auf den Index size(), denn sonst würde at() ja auch damit funktionieren
string s("Test"); cout << s.at(s.size()) << '\n'; // <- out_of_range exception
In der STL gibt es ein Unterschied ob der operator[] oder die Methode .at() aufgerufen wird.
operator[] - Keine Überprüfung ob der Index gültig ist -> siehe: http://ideone.com/Q079pU
at() - Überprüft den Index -> Exception, wie bei Deinem Code nachgewiesen.
-
Der Unterschied zwichen
operator[]
und.at()
ist mir schon klar. Manni66 bezieht sich allerdings auf den Ursprungspost wo es kein.at()
gibt.
-
sebi707 schrieb:
manni66 schrieb:
So wie es im Ursprungspost steht ist es richtig falsch, da auf einen Index ausserhalb des gültigen Wertebereichs zugegriffen wird.
Wo? Der
operator[]
erlaubt auch den Zugriff auf den Null Terminator.Wenn es C++ 11 ist, ja. Sonst nur für die const Version, die hier nicht benutzt werden dürfte.
Ob der gcc das in der "alten" libstd für C++ 11 schon richtig implementiert?
-
manni66 schrieb:
Ob der gcc das in der "alten" libstd für C++ 11 schon richtig implementiert?
Ja gut. Ich dachte C++11 kann man mittlerweile voraus setzen. Der ältere Standard garantiert zwar nichts aber mich würde schon extremst wundern wenn irgendeine Standardlibrary da jemals irgendwas komisches gemacht hat. Der Null Terminator muss dort ja eh stehen für den
operator[]() const
.
-
manni66 schrieb:
Wenn es C++ 11 ist, ja. Sonst nur für die const Version, die hier nicht benutzt werden dürfte.
Ernsthaft jetzt, bei der const Version war das erlaubt? Ich dachte immer auf den Null-Terminator kann man sich nur verlassen wenn man
.c_str()
verwendet, und sonst genau nirgends.
-
hustbaer schrieb:
Ernsthaft jetzt, bei der const Version war das erlaubt? Ich dachte immer auf den Null-Terminator kann man sich nur verlassen wenn man
.c_str()
verwendet, und sonst genau nirgends.Hat mich auch gewundert als ich letztens zu
std::string
was im Standard nachgeschlagen hab. Noch was eventuell Neues für dich wenn du nur beic_str
an den Nullterminator glaubtest: Diedata
Memberfunktion liefert genau das gleiche wiec_str
! Im Standard gibts nichtmal eine separate Beschreibung für beide...
-
Mh OK das scheint immerhin erst seit C++11 so zu sein...
-
Ja, das mit data ist ne C++11 Sache, und die war mir schon bekannt. Ich beziehe mich auf C++98 bzw. 03.
-
Okay danke jetzt weiß ich schonmal ungefähr was ich tun sollte, wenn ich soweit bin, werde ich versuchen das mit einem Algorithmus zu lösen. Ich danke euch auf jeden Fall für eure Antworten.
Ps: Wenn ich z. B. auf dieser Website Text in Binärcode übersetzen lassen will, kommt doch auch eine Null als erste Zahl ?
Mit freundlichem Gruß
-
Tha_Coralis schrieb:
Ps: Wenn ich z. B. auf dieser Website Text in Binärcode übersetzen lassen will, kommt doch auch eine Null als erste Zahl ?
Hat irgendwer behauptet, in Binärzahlen dürfen keine führende Nullen vorkommen?