Computerhilfen.de Logo
Forum
Tipps
News
Frage stellen

C(++): Universaler Datentyp, von dem man alle ableiten kann?

Hallo,

ich möchte aus einer Datei diverse Parameter auslesen, von denen ich zur Entwicklungszeit noch nicht den Datentyp weiß.

Gibt es einen universalen Datentyp, der später verschiedene "Formen annehmen" kann?
In Java oder Delphi ist mir noch dunkel Object eingefallen, von dem ich alle möglichen Sachen ableiten kann, gibt es etwas ähnliches auch in C (Wenn, dann wahrscheinlich eher C++, schätze ich)

Gruß Spawn


Antworten zu C(++): Universaler Datentyp, von dem man alle ableiten kann?:

Hat dir diese Antwort geholfen?

Danke ButtonHilfreiche Antwort Button

Hi Spawn |

Wenn du Daten aus einer Datei ausliest, dann bekommst du ja  nach meinem Verständnis erstmal einen String oder ein Char-Array. Bei Bedarf könntest du doch dann die Werte sicher konvertieren.

greez 8)
JoSsiF

Hat dir diese Antwort geholfen?

Danke ButtonHilfreiche Antwort Button

Ich nehme mal an, du lädst die Daten aus ner Binärdatei.

Java speichert die Datentypen in Form einer ID oder so immer mit, weshalb da sehr leicht wieder alles rekonstruiert werden kann.

Bei C/C++ ist das ja aber nicht so... das heißt, du musst wissen um welche Daten es sich handelt (sonst kann es ja noch nicht mal eine Zuordnung geben, wieviele Bytes z.B. zum ersten Parameter gehören.

Du könntest das System mit der ID natürlich selber nachbauen (du ließt also immer abwechslnd ne ID, nen normalen Int-Wert also, und dann ein entsprechendes Objekt.

Hat dir diese Antwort geholfen?

Danke ButtonHilfreiche Antwort Button

Danke für Eure Antworten!

Allerdings habe ich wohl mein Problem nicht ganz präzise zum Ausdruck gebracht :)

Nach meinen Vorstellungen soll meine Datei (bisher Textdatei, obwohl die Idee mit der Binärdatei natürlich auch sehr sinnvoll klingt) etwa so aussehen:

Zitat
s:1
deltax:9
deltay:12
rstart[d]:0.2
rstop[d]:0.8

Hierbei soll beispielsweise deltax der Variablenname sein, die Buchstaben die Dateitypen (hier bool, int und double) und alles nach dem ":" der Wert.

Das ich Variablen einführe, die dann so heißen wie in der Datei ist wahrscheinlich eine Illusion, aber ich hatte mir folgendes Konstrukt vorgestellt:

struct params
{
  int length;
  double* param;
};

Wie man am Code sieht, ist das derzeit auf Zahlen vom Typ double beschränkt.
Dafür habe ich bereits eine Routine geschrieben, die Strings in Double kovertiert.

Wen's interessiert: (ziemlich umständlich, aber scheint bisher zu funktionieren)

bool CSuperFilter::readParams(char* fileName, params* paramName, int expectedParams)
{
  FILE* logFile;
  logFile = fopen("logFile.txt", "w+");
  fprintf(logFile, "Log Start\n");

  char zeile[50];
  int zeilen = 0;
  char zeichen;
  FILE* file = fopen(fileName, "r");
  rewind(file);
  while(fgets(zeile, 50, file) != NULL)
    zeilen++;

  fprintf(logFile, "Zeilen: %d\n", zeilen);

  paramName->length = zeilen;
  paramName->param = new double[paramName->length];
  rewind(file);
  int afterPoint = 0;
  bool negativ = false;
  int paramNumber = 0;
  double value = 0;
  int tempValue;
  do
  {
    if((zeichen == '\n')||(zeichen == EOF)){
      //Zeile vollständig gelesen
      if(negativ) value *= -1;
      paramName->param[paramNumber] = value;

      fprintf(logFile, "Zeile %d: %f\n", paramNumber, value);

      paramNumber++;
      value = 0;
      afterPoint = 0;
      negativ = false;
    }
    else
    {
      if(zeichen == '.')
        afterPoint = 1;
      else
      {
        tempValue = Char2Byte(zeichen);
        if(tempValue == 10)
          negativ = true;
        else
        {
          if(afterPoint == 0)
          {
            value *= 10;
            value += tempValue;
          }
          else
          {
            value += tempValue/(pow(10,afterPoint));
            afterPoint++;
          }
        }
      }
    }
  }
  while(((zeichen = fgetc(file)) != EOF));
  fclose(file);

  fprintf(logFile, "Log Ende\n");
  fclose(logFile);
  if(paramName->length != expectedParams) return false;
  return true;
}

byte CSuperFilter::Char2Byte(char c)
{
  byte temp = 0;
  switch(c) {
    case '0': temp = 0;break;
    case '1': temp = 1;break;
    case '2': temp = 2;break;
    case '3': temp = 3;break;
    case '4': temp = 4;break;
    case '5': temp = 5;break;
    case '6': temp = 6;break;
    case '7': temp = 7;break;
    case '8': temp = 8;break;
    case '9': temp = 9;break;
    case '-': temp = 10;break;
    default: temp = 0;
  }
  return temp;
}

Da gibt es noch den Fehler, dass die letze Zeile in der Datei mit \n abschließen muss, aber das nur am Rande...

Diese Variante liest aber nur pure Zahlen auf Zeilen verteilt und eben nur double, ich würde aber gern verschiedene Varianten auslesen mit einem Konstrukt wie folgt (frei erfunden):

struct params
{
  int length;
  UniversalTyp* param;
};

Damit könnte ich dann theoretisch im Programm sagen etwas in der Art machen:

params para;
para->length = bla;
para->param[0] = 12345;
para->param[1] = "Hallo";
.
.
int bla = (int)para->param[0];
String blup = (String)para->param[1];

So ungefähr hatte ich mir das vorgestellt und suche eben diesen universalen Typ, der später verschiedene Typen sein kann. Das geht wie gesagt in Java mit Object, aber in C++ kenn ich das Ganze leider nicht.

Danke für's Lesen dieses ganzen Zeugs ;)


Edit: Hab noch den Code formatiert zum besseren Lesen.
« Letzte Änderung: 12.10.06, 18:02:41 von Spawn »

Hat dir diese Antwort geholfen?

Danke ButtonHilfreiche Antwort Button

Mal eine ganz andere Idee: schonmal über Serialisierung nachgedacht? Weiß nicht genau, ob's zu deinem Programm passt (hab mir den Quellcode auch nicht reingezogen wennich ehrlich bin ;)), aber vielleicht wäre das ja etwas für dich :)

greez 8)
JoSsiF

Hat dir diese Antwort geholfen?

Danke ButtonHilfreiche Antwort Button

Du kannst dir so nen Ober-Datentyp ja selber basteln...
Du machst dir ne leere Klasse oder Struct und nennst das dann von mir aus "Object" oder wie auch immer

struct Object
{
};

und dann musst Du Rapper-Klassen (so hießen die doch glaube ich ::) ) schreiben, z.B.

struct Boolean : public Object {
  bool wert;
};
struct Double : public Object {
  double wert;
};
...

und dann kanst du so was machen wie
struct params
{
  int length;
  Object* param;
};

vieleicht würde sogar so was wie
struct params
{
  int length;
  void* param;
};
gehen... aber wenn Du so eine Object-Klasse hättest, dann könntest Du halt dort auch z.B. den Variablennamen als String-Attribut mit rein packen

Ich weiß ja nicht, was Du da machen willst, alles in allem scheint mir das aber bisl umständlich...
sind es denn immer total unterschiedliche Werte die Du da aus den Dateien liest oder würde es so was wie
struct params {
  bool s;
  int deltax;
  int deltay;
  double rstart;
  double rstop;
};
nicht auch tun?
« Letzte Änderung: 12.10.06, 19:57:42 von mati »

Hat dir diese Antwort geholfen?

Danke ButtonHilfreiche Antwort Button

Hmm, Object selber bauen ist eigentlich gar keine blöde Idee...ja, das wäre einen Versuch wert.

Und ja, ich brauche absolute Unabhängigkeit (in einem vorgegebenem Rahmen). Dazu vielleicht eine kurze Zusammenfassung der Software: Sie verändert Daten nach einem bestimmten Muster. Die Art und Weise der Transformierung soll flexibel und vom (erfahrenen)Endanwender anpassbar sein, deshalb habe ich Plugins eingeführt, so dass quasi jeder ein Plugin schreiben kann ohne an der Software rumbasteln zu müssen.
Diese Plugins wiederum benutzen eine Rechenvorschrift, die dann wiederum auch vom nicht erfahrenen Anwender durch Parameter "feingetunt" werden kann. Und da ich noch nicht weiß, welche Parameter ein Plugin benutzen will und diese Last auch nicht auf den Plugin-Entwickler abwälzen will, sollen sie eben flexibel einsetzbar sein.

Obwohl, jetzt wo ich das Ganze so aufschreibe.....eigentlich weiß der Plugin-Entwickler ja sehr genau, was er für Parameter haben will. Dann könnte man das ja doch fest machen... ::)

Shit, muss nachdenken und diverse Pläne über den Haufen werfen :-\

@JoSsiF: Ich habe mich bei Wikipedia mal über Serialisierung belesen wollen, war allerdings recht theoretisch. Hast Du vielleicht ein "Vorzeige-Beispiel" parat, wo und wie sowas eingesetzt wird?

Bis hierhin tausend Dank, ich meld mich, wenn ich wieder klare Gedanken fassen kann (egal ob Ihrs hören wollt ;) )

Spawn

Hat dir diese Antwort geholfen?

Danke ButtonHilfreiche Antwort Button

Okay, habe mir alles nochmal gut überlegt und meine bisherigen Pläne als überstürzt und unnötig aufwendig eingestuft.
Wie war das noch mal? "Die meisten Zeit zum Erstellen von Software sollte man in den Entwurf der Architektur investieren und nicht in das Umsetzen" oder so? Naja, typischer Fall....

Habe mich jetzt entschieden, dass ein Plugin-Entwickler festlegen muss, welche Werte er in einer Datei erwartet. Somit muss er auch den params-Struct vorgeben, damit arbeiten und die eigentliche Software bekommt nur die Resultate der Berechnung.

Vielen Dank für Eure guten Ideen und Gedankenanstöße :)

Spawn


« selbst kopierenProgramm ändern »
 

Schnelle Hilfe: Hier nach ähnlichen Fragen und passenden Tipps suchen!

Fremdwörter? Erklärungen im Lexikon!
Auslagerungsdatei
Die Auslagerungsdatei, auch bekannt als virtueller Speicher, ist ein wichtiges Element im Windows-Betriebssystem. Sie dient als Erweiterung des physischen Arbeitsspeicher...

Dateiendungen
Die Dateiendung, auch Dateinamenerweiterung, Dateierweiterung oder einfach "Endung" genannt, besteht aus meistens drei oder vier Buchstaben und wird mit einem Punkt an de...

Dateisystem
Das Dateisystem eines Computers definiert, wie Daten auf einem Speichermedium organisiert werden. Es bestimmt dabei, wie die Informationen auf dem Medium gespeichert, gel...