# String in einer Struktur C++



## schlappe89 (20. Januar 2011)

Hi,

ich will einen String in eine Struktur packen, weiß nicht genau wie es funktioniert und finde im Internet nichts hilfreiches.

So ähnlich stand es im Script des Profs:


```
#include "bla.h"
#include <iostream>
#include <string>
using namespace std;
void main()
{
    bla s;
    s.mystring="Text";
    cout<<s.mystring;
    
}
```
Das ist die Headerdatei bla.h :

```
struct bla
{
    string mystring;
};
```
Wenn ich das mit Visual Studio 2010 starte bekomme ich diese Fehler:


```
1>------ Erstellen gestartet: Projekt: string struct test, Konfiguration: Debug Win32 ------
1>Der Buildvorgang wurde am 20.01.2011 17:49:48 gestartet.
1>InitializeBuildStatus:
1>  Aktualisieren des Timestamps von "Debug\string struct test.unsuccessfulbuild".
1>ClCompile:
1>  main.cpp
1>d:\projekte c++\string struct test\string struct test\bla.h(3): error C2146: Syntaxfehler: Fehlendes ';' vor Bezeichner 'mystring'
1>d:\projekte c++\string struct test\string struct test\bla.h(3): error C4430: Fehlender Typspezifizierer - int wird angenommen. Hinweis: "default-int" wird von C++ nicht unterstützt.
1>d:\projekte c++\string struct test\string struct test\bla.h(3): error C4430: Fehlender Typspezifizierer - int wird angenommen. Hinweis: "default-int" wird von C++ nicht unterstützt.
1>d:\projekte c++\string struct test\string struct test\main.cpp(8): error C2039: 'mystring': Ist kein Element von 'bla'
1>          d:\projekte c++\string struct test\string struct test\bla.h(2): Siehe Deklaration von 'bla'
1>d:\projekte c++\string struct test\string struct test\main.cpp(9): error C2039: 'mystring': Ist kein Element von 'bla'
1>          d:\projekte c++\string struct test\string struct test\bla.h(2): Siehe Deklaration von 'bla'
1>
1>Fehler beim Erstellen
1>
1>Verstrichene Zeit 00:00:00.57
========== Erstellen: 0 erfolgreich, Fehler bei 1, 0 aktuell, 0 übersprungen ==========
```
Wo liegt das Problem?


----------



## bingo88 (20. Januar 2011)

Da fallen mir spontan 2 Punkte ein:

1. Hast du "#include <string>" im Header?
2. Du müsstest std::string angeben. Von "using namespace std;" ist im Header dringend abzuraten. Das gilt nämlich dann für alle Dateien, die den Header einbinden würden, was zur Verdeckung von Namen führen kann.


----------



## schlappe89 (20. Januar 2011)

> #include "bla.h"
> #include <iostream>
> #include <string>
> using namespace std;
> ...


Das ist meine main Funktion. Darin eingebunden ist bla.h <iostream> und <string>
Wir haben bei uns nur mit using namespace *std* gelernt, also daran sollte es nicht liegen oder?


----------



## bingo88 (20. Januar 2011)

bla.h

```
#pragma once

#include <string> // wichtig, sonst findet der std::string nicht

struct bla
{
    std::string mystring;
};
```

main.cpp

```
#include "bla.h"
#include <iostream>

using namespace std; // hier ok, oben nicht

int main(int argc, char *argv[])
{
    ...
}
```


----------



## schlappe89 (20. Januar 2011)

Was hat das #pragma once zu bedeuten?

Ich hab jetzt folgende Header Datei:

```
#include <string>
struct bla
{
	string mystring;
};
```

Funktioniert leider nicht. Gleicher Fehler.

Was meinster du damit? 
	
	



```
using namespace std; // hier ok, oben nicht
```


----------



## bingo88 (20. Januar 2011)

schlappe89 schrieb:


> Was hat das #pragma once zu bedeuten?
> 
> Ich hab jetzt folgende Header Datei:
> 
> ...


std:: fehlt?

#pragma once (Präprozessoranweisung) verhindert, dass die Datei mehrfach geparst wird (führt ansonsten zu Fehlern). Das gibt es auch mit

```
#ifndef _MYHEADER_H_
#define _MYHEADER_H_

// CODE

#endif
```



schlappe89 schrieb:


> Was meinster du damit?
> 
> 
> 
> ...


using namespace sollte nicht in Header-Dateien eingesetzt werden. Du bindest Header ja idR mehrfach ein. Wenn du jetzt using namespace xyz im Header angibst, wird das für alle Dateien übernommen, die diesen Header einbinden. Das kann zu ziemlich bösen Fehlern führen. Using namespace sollte daher nur in cpp Dateien auftauchen und auch erst nach allen #includes

(Durch using namespace xyz in einem Header wird der Namensraum xyz mit dem globalen Namensraum verschmolzen. Hast du jetzt einen Typ meintyp im globalen NR und einen Typ meintyp im NR xyz wirst du kein Programm mehr kompiliert bekommen und du darfst dich auf die lange Suche begeben, warum der Compiler nicht will)


----------



## schlappe89 (20. Januar 2011)

Jo danke, das mit dem string klappt jetzt wunderbar 
Schade dass mein Prof das nicht so in sein dummes Skript schreiben kann.


----------



## bingo88 (20. Januar 2011)

Jo, kein Thema. Ich kenne diese "ausführlichen" Skripte aber auch


----------



## Zappzarrap (21. Januar 2011)

Warum willst du den String überhaupt in eine Liste packen? Wenn du (mehrere) Strings speichern willst gibt es in der STL um einiges bessere Möglichkeiten, wie <vector>

Kannst ja hier mal schauen:

STL Containers - C++ Reference

Die bringen meistens auch eigene methoden zum Sortieren, durchiterieren etc mit sich...Sehr viel angenehmer zu verarbeiten als eine Liste. Du kannst dein struct übrigens auch einfach mit class ersetzen und vor deinen String public schreiben...Kommt auf´s gleiche heraus in diesem Fall...


----------



## bingo88 (21. Januar 2011)

Von einer Liste war doch überhaupt nicht die Rede


----------



## Zappzarrap (21. Januar 2011)

struct ist ne Liste


----------



## schlappe89 (21. Januar 2011)

Ich wills nicht zu kompliziert machen.
Muss für die Hochschule ein Programm schreiben, und wir haben das mit string gemacht.
Ich werd mir deinen Link später mal anschauen.


----------



## bingo88 (21. Januar 2011)

> struct ist ne Liste


Ich glaube wir haben eine unterschiedliche Vorstellung von "Listen" 

Meinem Verständins nach ist ein "struct" ein Datentyp der andere Datentypen beinhaltet - also kapselt (in C++ kann struct allerdings wie eine Klasse gehandhabt werden, nur ist standardmäßig alles public und nicht private).


```
struct CPU_CAPS
{
    bool hasMMX;
    bool hasSSE;
    bool hasSSE2;
};

...

CPU_CAPS caps; // das hier hat doch nix mit einer Liste zu tun ???
cpu_get_caps(&caps);

if (caps.hasMMX)
    printf("MMX supported\n");
if (caps.hasSSE)
    printf("SSE supported\n");
if (caps.hasSSE2)
    printf("SSE2 supported\n");

...
```

Und eine Liste ist für mich eine mehr oder weniger dynamische Ansammlung gleichartiger Datentypen, z. B. Vector (Arraylist) oder List (verkettete Liste) in der STL


----------



## Zappzarrap (21. Januar 2011)

Wir haben es so gelernt...Unser prof hat im Zusammenhang mit "struct" immer von Listen gesprochen...Und wenn du dir deinen Code anschaust ist es ja auch nichts anderes, eine sammlung gleichartiger Datentypen...Du kannst auch Integer Elemente in deine Liste packen...Dann zeigt ein Listenelement immer auf´s nächste, das wäre dann eine einfach verzeigerte Liste...



> *Verkettete Listen*
> 
> Wenn Sie mehrere Elemente eines Typs brauchen, werden Sie automatisch an ein Array denken. Wenn es aber vor der ersten Speicheranforderung schwer  möglich ist, die maximale Anzahl der Elemente abzuschätzen,  sind verkettete Listen eine gute Lösung. Wird ein neues Datenelement benötigt, wird es erzeugt und in die Liste eingefügt. Benötigen Sie ein Element nicht mehr, wird es gelöscht. Wie viele Elemente in der Liste sind, ist nur durch den verfügbaren Speicher beschränkt. Der Zugriff auf die Elemente  an einer bestimmten Positionsnummer ist allerdings aufwändiger als in einem  Array.  *Daten und Zeiger*
> 
> Die Basis einer verketteten Liste ist eine Struktur, die einerseits die  eigentlichen Daten und andererseits einen Zeiger enthält, um auf das nächste  Element der Liste zu verweisen.




```
struct TListenKnoten
{
    int data;
    TListenKnoten *next;
};
```
Kannst du hier nachlesen:

Dynamische Strukturen in C++

€dit:

Allerdings habe ich Listen, seitdem wir mit c++ arbeiten garnicht mehr benutzt...Ganz am Anfang mal bevot wir klassen hatten. Ich würde das eher mit Klassen realisieren. In deinem Fall @Bingo zb eine Klasse mit den verschiedenen Prozessoreigenschaften und die Abfrage was es ist in den Konstruktor. Dann kannst du dir Objekte mit der entsprechenden Eigenschaft erstellen und später mit methoden daraufzugreifen...In etwa so:


```
class CPU_PROP{

public:

    CPU_PROP();           //Konstruktor
    ~CPU_PROP();         //Destruktor

};

/************Und in die cpp:*****************************/

CPU_PROP::CPU_PROP(){
//Dein Code
}
```


----------



## bingo88 (21. Januar 2011)

Aso, da hast du jetzt leider etwas missverstanden 


```
struct TListenKnoten
{
    int data;
    TListenKnoten *next;
};
```
Das ist ein Listenelement, das in einem struct gekapselt ist (hier: Datum + Zeiger auf nächstes Element). Die Liste entsteht dadurch, dass der Zeiger auf ein weiteres Listenelement zeigt, das hat mit dem Schlüsselwort Struct aber erst mal nichts zu tun.

Verbund (Datentyp) ? Wikipedia
Da ist erklärt was ein struct ist (struct != Liste)


> Strukturen dürfen auch andere Strukturen enthalten, jedoch nicht sich  selbst, weil die Größe einer Struktur damit undefiniert wäre. Ein Zeiger auf sich selbst ist jedoch möglich – auf diese Weise werden beispielsweise verkettete Listen erzeugt.



Edit: Naja, 1. war das aus nem C-Projekt von mir, 2. ist ne Klasse für reine Datenhaltung overkill (es sind nur 3 bools...)


----------



## Zappzarrap (21. Januar 2011)

Gut sogesehen hast du natürlich recht, da ist ne Liste nicht viel mehr als ein Datenbunker. 

Wir haben Listen *nur* so benutzt...ich mein 3 bools kann man sich auch mal eben deklarieren...Halte ich für recht sinnfrei die in eine liste packen. Das Klassenkonzept sorgt allerdings dafür das du dein Programm relativ einfach erweitern kannst...ich weiss nicht was du damit vorhast, aber spätestens wenn und wirklich mal irgendwas berechnen willst brauchst du methoden...zumindest wenn du objektorientiert proggen willst. Wenn dein Programm aber nur prüft was für eine Prozessorerweiterung vorhanden ist, reicht das natürlich aus. Aber ich denke das ist auch sehr vom Prof abhängig...Unserer hat uns eingebläut für jeden S***** Ne Klasse oder umindest ne Unterklasse zu machen...


----------



## bingo88 (21. Januar 2011)

So jetzt mal ein wenig mehr 


```
// cpu_tools.h
#pragma once

typedef struct S_CPU_CAPS
{
    bool hasMMX;
    bool hasSSE;
    bool hasSSE2;
} CPU_CAPS, *PCPU_CAPS;

void cpu_get_caps(PCPU_CAPS pcaps);
```


```
// cpu_tools.cpp
#include "cpu_tools.h"

// ... Konstantendeklarationen

void cpu_get_caps(PCPU_CAPS pcaps)
{
    int retval = 0;

    if (pcaps == NULL)
        return;

    // [...] CPU flags auslesen

    if (retval & MMX_FLAG) // hier ist wirklich "&" gemeint
        pcaps->hasMMX = true;
    else
        pcaps->hasMMX = false;

    // für den Rest genauso
}
```


```
// main.cpp
#include <stdio.h>
#include "cpu_tools.h"

CPU_CAPS g_cpu_caps;

int main(int argc, char *argv[])
{
    // ...

    cpu_get_caps(&g_cpu_caps); // Struktur füllen, muss nur 1x gemacht werden

    // ...
    return 0;
}
```
Eine Struktur als Liste zu bezeichnen, ist schlicht falsch. Man kann aus Strukturen (oder auch Klassen) aber Listen bauen, wenn man die entsprechende Logik implementiert.


----------



## schlappe89 (21. Januar 2011)

Also ich hab das Programm heute morgen vorgezeigt und es wurde abgenickt.
Wenns jemanden interessiert hier die Aufgabenstellung:
https://www.fbi.h-da.de/fileadmin/personal/n.spangler/EIT_Informatik/praktikum/praktikum12.pdf

Ich kann den Quelltext auch mal hochladen wenn jemand ihn sehen will.

Bei uns bauen die Vorlesungen aufeinander auf. Diese Vorlesung und die Aufgabe galt dem Verständnis von Strukturen und eventuell noch Zeigern.


----------



## KingofKingzZ (22. Januar 2011)

@ Zappzarrap

Eine Struktur hat erstmal gar nichts mit Listen zu tun. In C++ ist es im Prinzip das selbe wie ne Klasse, nur dass standardmäßig alles public ist. Eine Struktur besitzt genauso wie eine Klasse einen Konstruktor etc. und kann ebenfalls Funktionen enthalten. Die meisten Leute verwenden Strukturen, wenn man mehrere Variablen zu einem Objekt zusammenfassen will.

Das hier: 


```
struct TListenKnoten
{
    int data;
    TListenKnoten *next;
};
```

wäre nur ein Element einer Liste, aber nicht die Liste selbst. Du könntest z.B. genauso das hier als Element einer Liste benutzen: 


```
class TListenKnoten
{
public: 
     int data; 
     TListenKnoten *next; 
};
```

Hier hast du es selbst zitiert: 



> Die *Basis* einer verketteten Liste ist eine *Struktur*, die einerseits die eigentlichen Daten und andererseits einen *Zeiger* enthält, um auf das *nächste Element* der Liste zu verweisen.



lg KoK


----------

