Forum: PC-Programmierung In C++ Dantenströme übergeben


von HasProblemsWithCpp (Gast)


Lesenswert?

Tschou Zämä

Ich versuche, ein Struct für eine imaginäre Zahl ein- und auszulesen. 
Dafür möchte ich iostream verwenden und diesen in die Methode übergeben. 
Irgendwie geht's nicht und die Fehlermeldung hilft mir auch nicht 
weiter...
Wer findet das Problem?
Vielen Dank im Voraus!
1
#include <iostream>
2
#include <cmath>
3
#include <cstring>
4
using namespace std;
5
typedef string::iterator itStr;
6
double epsilon = 0.00001;
7
8
struct cNumb{
9
    double a; // a+
10
    double b; //b*i
11
};
12
13
cNumb add(const cNumb c1, const cNumb c2);
14
cNumb operator + (const cNumb c1, const cNumb c2);
15
cNumb sub(const cNumb c1, const cNumb c2);
16
cNumb operator - (const cNumb c1, const cNumb c2);
17
cNumb multiply(const cNumb c1, const cNumb c2);
18
cNumb operator * (const cNumb c1, const cNumb c2);
19
cNumb complement(const cNumb c1);
20
double radOrAbs(const cNumb c1); // radius == Betrag
21
// Divisor, Dividend
22
cNumb divise(const cNumb c1, const cNumb c2);
23
cNumb operator / (const cNumb c1, const cNumb c2);
24
bool operator ==(const cNumb c1, const cNumb c2);
25
bool operator != (const cNumb c1, const cNumb c2);
26
27
cNumb read(istream& in, const cNumb c1);
28
//cNumb operator >> (istream& in, const cNumb c1);
29
30
void write( ostream& out,const cNumb c1);
31
//void operator << ( ostream& out, const cNumb c1);
32
33
int main(){
34
    bool run = true;
35
    while(run){
36
        cNumb c; 
37
        read(&cin, c); 
38
        write(&out, c); 
39
        cout << "\nWieder?";
40
        cin >> run;
41
    }
42
    return 0;
43
}
44
45
void write(ostream& out, const cNumb c1){
46
    (&out) << " " << c1.a << " + "<< c1.b << "i";
47
}
48
/*
49
void operator << (ostream& out, const cNumb c1){
50
    write(out, c1);
51
}
52
*/
53
cNumb read(istream& in, const cNumb c1){
54
    string input;
55
    &in >> input;
56
    c1.a = 0;
57
    c1.b = 0;
58
    bool readingA = true;
59
    bool readingB = false;
60
    bool aNegative;
61
    bool bNegative;
62
63
    for(itStr i = input.begin(); i<input.end(); i++){
64
        if(readingA && *i== '-'){
65
            aNegative = true;
66
        }
67
        if(readingA && *i>47 && *i<58){
68
            c1.a = c1.a*10 +*i;
69
        }else{
70
            readingA = false;
71
            readingB = true;
72
        }
73
        if(readingB && *i== '-'){
74
            bNegative = true;
75
        }
76
        if(readingB&& *i>47 && *i<58){
77
            c1.b = c1.b*10 +*i;
78
        }else if(*i == 105){
79
            break;
80
        }
81
        // Alternative: Ganz normal output : cout << "a = "; cout << "b = "
82
    }
83
}

: Bearbeitet durch User
von Mark B. (markbrandis)


Lesenswert?

1
g++ -Wall -Wextra main.cpp -o main.exe
2
3
main.cpp: In function `int main()':
4
main.cpp:37: error: invalid initialization of non-const reference of type 'std::istream&' from a temporary of type 'std:
5
:istream*'
6
main.cpp:27: error: in passing argument 1 of `cNumb read(std::istream&, cNumb)'
7
main.cpp:38: error: `out' was not declared in this scope
8
main.cpp:38: warning: unused variable 'out'
9
main.cpp: In function `void write(std::ostream&, cNumb)':
10
main.cpp:46: error: invalid operands of types `std::ostream*' and `const char[2]' to binary `operator<<'
11
main.cpp: In function `cNumb read(std::istream&, cNumb)':
12
main.cpp:55: error: no match for 'operator>>' in '+in >> input'
13
main.cpp:56: error: assignment of data-member `cNumb::a' in read-only structure
14
main.cpp:57: error: assignment of data-member `cNumb::b' in read-only structure
15
main.cpp:68: error: assignment of data-member `cNumb::a' in read-only structure
16
main.cpp:77: error: assignment of data-member `cNumb::b' in read-only structure

Na nu komm aber. Zumindest ein paar von diesen Fehlern kannst Du selbst 
beheben.

von Klaus W. (mfgkw)


Lesenswert?

Zudem sollte man ihm vielleicht noch verraten, daß man das eh mit 
Überladen des Operators << wesentlicher eleganter und C++-konformer 
machen kann?

von Rolf Magnus (Gast)


Lesenswert?

Mal ganz davon abgesehen, daß es in C++ schon ein Template für komplexe 
Zahlen gibt. Da sind diese ganzen Operationen und noch einige mehr schon 
definiert.
Siehe http://www.cplusplus.com/reference/complex/ und
http://www.cplusplus.com/reference/complex/complex/operators/

von HasProblemsWithCpp (Gast)


Lesenswert?

Es geht um die Theorie, darum, das Struct zu verstehen etc.
Den Operator << möchte ich später auch noch einführen, für Addition und 
weiteres habe ich das schon gemacht.
Was sind denn diese 'offensichtlichen' Fehler?

Von Datenströmen verstehe ich noch recht wenig.

von Matthias H. (hallamen)


Lesenswert?

HasProblemsWithCpp schrieb:
> Von Datenströmen verstehe ich noch recht wenig.

Du meintest wohl "Von C++ verstehe ich noch recht wenig." :)

Zu den fehlern:
In den Zeilen 37,38,46,55:
Das '&' vor den Objekten weglassen bzw. das Kapitel 'Referenzen' in 
einem C++ Buch deiner Wahl durchlesen.

Zeilen 56,57,68,77:
'const' sagt dem Compiler, dass ein Parameter einer Funktion nicht 
verändert wird, du versuchst es aber trotzdem...

von Karl H. (kbuchegg)


Lesenswert?

Matthias H. schrieb:

> 'const' sagt dem Compiler, dass ein Parameter einer Funktion nicht
> verändert wird, du versuchst es aber trotzdem...


Wobei die Sache hier noch weiter geht. Das ist die bewusste Funktion
1
cNumb read(istream& in, const cNumb c1){
2
....

Wenn die Funktion read ein cNumb Objekt als Returnwert liefert, wozu 
braucht es dann noch eines als Funktionsargument? Was macht es damit? 
Wozu ist dieses nötig?

Bei write ist das so ok, denn write muss ja wissen, welches cNumb Objekt 
ausgegeben werden soll. D.h. das muss man dem übergeben. Aber read?

Mir scheint, da gibt es noch mehr Probleme ganz banalerer Natur als nur 
Strukturen.

von Karl H. (kbuchegg)


Lesenswert?

1
cNumb read(istream& in, const cNumb c1){
2
    string input;
3
    &in >> input;

Die Sache mit den Referenzen hast du nicht wirklich verstanden. Oder?
Das Referenz-& in der Argumentliste bedeutet nicht, dass du einfach dann 
überall ein & schreiben musst. Ganz im Gegenteil.

von PittyJ (Gast)


Lesenswert?

Warum nimmt man ein struct für complexe Zahlen und nicht gleich eine 
Klasse?

von Dr. Sommer (Gast)


Lesenswert?

PittyJ schrieb:
> Warum nimmt man ein struct für complexe Zahlen und nicht gleich eine
> Klasse?
Um das "public:" zu sparen :D

von Fred (Gast)


Lesenswert?

Ein struct ist doch auch nur eine Klasse.

von Mark B. (markbrandis)


Lesenswert?

/me empfiehlt die Lektüre eines C++ Buches

von Mark B. (markbrandis)


Lesenswert?

A propos, was sind eigentlich Dantenströme? Hat das was hiermit zu tun?

http://de.wikipedia.org/wiki/G%C3%B6ttliche_Kom%C3%B6die

;-)

von HasProblemsWithCpp (Gast)


Lesenswert?

Es geht nicht um eine alte Komödie, aber auch mir scheint Kerberos den 
Eintritt in die C++-Welt zu verwehren.

Vieles konnte ich beheben! Ein Fehler bleibt:

Es geht um den iostream, genauer um den istream, um cin. Ich kann den 
cin nicht anderorts verwenden, nachdem ich ihn read() übergeben habe.

Das Programm sollte fragen, ob es nochmals durchlaufen soll.
Für andere Projekte hat es wunderbar funktioniert -> das Problem liegt 
beim cin.

--------------------Aktuelle Version------------------
1
#include <iostream>
2
#include <cmath>
3
#include <cstring>
4
using namespace std;
5
typedef string::iterator itStr;
6
double epsilon = 0.00001;
7
8
struct cNumb{
9
    double a; // a+
10
    double b; //b*i
11
};
12
13
cNumb read(istream& in);
14
cNumb operator >> (istream& in, cNumb c);
15
16
void write(ostream& out, const cNumb c);
17
void operator << ( ostream& out, const cNumb c1);
18
19
int main(){
20
    bool run = true;
21
    while(run){
22
        cNumb c;
23
        c = read(cin);
24
        write(cout, c);
25
        cout << "\nWieder?";
26
        cin >> run;
27
    }
28
    return 0;
29
}
30
31
void write(ostream& out, const cNumb c1){
32
    out << " " << c1.a<< " + "<< c1.b << "i";
33
}
34
35
void operator << (ostream& out, const cNumb c1){
36
    write(out, c1);
37
}
38
39
cNumb read(istream& in){
40
    cNumb res;
41
    res.a = 0;
42
    res.b = 0;
43
    string input;
44
    while(in.peek()!= 'i'){
45
            input += in.get();
46
    }
47
    input += 'i';
48
    bool readingA = true;
49
    bool aNegative = false;
50
    bool bNegative = false;
51
    for(itStr i = input.begin(); i<input.end(); i++){
52
        if(readingA){
53
            if(*i == '-'){
54
                aNegative = true;
55
                i++;
56
            }
57
            while(*i>='0' && *i<='9'){
58
                res.a = res.a*10 +((*i)-48);
59
                i++;
60
            }
61
            readingA = false;
62
        }else{
63
            if(*i== '-'){
64
                bNegative = true;
65
                i++;
66
            }
67
            while(*i>='0' && *i<='9'){
68
                res.b = res.b*10 + ((*i)-48);
69
                i++;
70
            }
71
        }
72
    }
73
    if(aNegative){
74
        res.a = -res.a;
75
    }
76
    if(bNegative){
77
        res.b = -res.b;
78
    }
79
    return res;
80
}
81
82
cNumb operator >> (istream& in, cNumb c1){
83
    return read(in);
84
}

: Bearbeitet durch User
von Rolf Magnus (Gast)


Lesenswert?

HasProblemsWithCpp schrieb:
> Es geht um den iostream, genauer um den istream, um cin. Ich kann den
> cin nicht anderorts verwenden, nachdem ich ihn read() übergeben habe.

Bei der Eingabe drückst du doch bestimmt am Ende Enter, oder? Ich sehe 
nirgends, daß das abgeholt wird, also steht es noch im Stream-Puffer 
wenn du "Wieder?" fragst, und dann wird das gelesen.

von HadProblemsWithCpp (Gast)


Angehängte Dateien:

Lesenswert?

Problem gelöst: Es fehlten sentry, clear() und ignore().

Vielen Dank für die Hilfe.

von Karl H. (kbuchegg)


Lesenswert?

So ganz versteh ich noch nicht, warum read nicht einfach so aussehen 
kann
1
cNumb read(istream& in)
2
{
3
  cNumb res;
4
  char c;
5
  char imag;
6
7
  in >> res.a >> c >> res.b >> imag;
8
9
  return res;
10
}
aber das wirst du schon wissen, warum das so (in meinen Augen) 
kompliziert sein muss.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

PS:
Hast du schon von Referenzen gelernt?

Denn hier
1
cNumb add(const cNumb c1, const cNumb c2){
2
...
kannst du dir das const auch sparen.
Beim Funktionsaufruf wird sowieso eine Kopie des Arguments des Aufrufers 
gemacht. Ob du die in der Funktion veränderst oder nicht spielt keine 
Rolle, da diese Kopie nach Beendigung der Funktion sowieso zerstört 
wird.

So hingegen
1
cNumb add(const cNumb& c1, const cNumb& c2){
2
...
ist das const wichtig, weil jetzt keine Kopie mehr gemacht wird, sondern 
die Funktion mit den Originalen des Aufrufers arbeitet. Und in dem Fall 
ist es wichtig, dem Aufrufer die Zusicherung zu geben: Die Funktion wird 
die beim Aufruf angegebenen Argumente nicht verändern.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.