Pfad des ifstream Objects mit dem dieses Instanziiert wurde



  • Hey Sewing, arbeitest du da mit klassischen Punktwolken aka 3D Messpunkte von Laserscannern o.ä.?

    Kennst du die PCL (http://www.pointclouds.org/)? Ich habe das Gefühlt, dass dir die Bibliothek evt. einiges an Arbeit sparen könnte.



  • vielen lieben Dank!

    Das heißt die Methode, die ich verwendet habe, wäre eher geeignet für den Fall, dass der key auch in den files steht und nicht wie hier schon vorher feststeht ja?

    std::map hat ja kein push_back, weshalb ich nicht darauf gekommen bin, dass man das umgehen kann, indem man den mapped-type, dh. std::vector push_backed, indem man schon im Funktionsaufruf von back_inserter den mapped type übergibt. Genial...

    verwendet std::istream_iterator by-default '\n' als delimiter oder wieso liest er immer genau einen Punkt ein?

    allerdings muss ja mein Point3D hierfür wegen operator[] default constructible sein...

    ich wüsste dennoch gerne, was an meinem code falsch war...



  • Schlangenmensch schrieb:

    Hey Sewing, arbeitest du da mit klassischen Punktwolken aka 3D Messpunkte von Laserscannern o.ä.?

    Kennst du die PCL (http://www.pointclouds.org/)? Ich habe das Gefühlt, dass dir die Bibliothek evt. einiges an Arbeit sparen könnte.

    es sind tatsächlich .pcd files ; )

    nur will ich vermeiden, dieses monster als Abhängigkeit zu verwenden, und da ich nur ein paar files einlesen muss, wollte ich mir da anderweitig behelfen ; )



  • Sewing schrieb:

    Das heißt die Methode, die ich verwendet habe, wäre eher geeignet für den Fall, dass der key auch in den files steht und nicht wie hier schon vorher feststeht ja?

    Ich glaube Du denkst zu kopmpliziert:

    void Parser::ExtractFromFiles()
    {
        for (auto const& filename : FileNames_) {
    
            std::ifstream inputFile{ filename };
            std::string pointCloudName;
            inputFile >> pointCloudName;
            std::copy(std::istream_iterator<Point3D>{inputFile}, std::istream_iterator<Point3D>{}, std::back_inserter(pointClouds_[pointCloudName]));
        }
    }
    

    Sewing schrieb:

    std::map hat ja kein push_back, weshalb ich nicht darauf gekommen bin, dass man das umgehen kann, indem man implizit den std::vector push_backed, indem man schon im funktionsaufruf von back_inserter den mapped type übergibt. Genial...

    Hä? pointClouds_[filename] aus Zeile 38 ist ein std::vector<Point3D> ... da wird garnichts implizit "push_backed".

    Sewing schrieb:

    ich wüsste dennoch gerne, was an meinem code falsch war...

    ich wüsst nicht wo anfangen 😕



  • habs meine formulierung im vorhergehenden post angepasst.

    hatte das zunächst so gelöst

    for (auto const& filename : FileNames_) {
    
          std::ifstream inputFile{ filename };
          assert(inputFile.is_open() && !inputFile.fail());
    
                std::istringstream istr;
                std::vector<Point3D> cloud;
                for (std::string buffer{}; std::getline(inputFile, buffer);) {
                  std::stringstream lidarPoint{ buffer };
    
          std::copy(std::istream_iterator<Point3D>{ lidarpoint },
                    std::istream_iterator<Point3D>{},
                    std::back_inserter(cloud));
        }
              pointClouds_.emplace(filename, cloud);
      }
    

    weil ich dachte, es sei notwendig explizit Zeile für Zeile des Files einzulesen, offenbar ist es das nicht...

    generell hatte ich versucht das Beispiel aus dem Buch hier anzuwenden

    [url=http://666kb.com/i/dr6ge245c98e4xjkt.jpg] 1
    [/url]
    [url=http://666kb.com/i/dr6gefgq9xxz182u5.jpg] 2
    [/url]
    3



  • sewing schrieb:

    verwendet std::istream_iterator by-default '\n' als delimiter oder wieso liest er immer genau einen Punkt ein?

    std::istream_iterator verwendet den für Deinen Punkt3D definierten operator>>(std::istream&,Point3D&) ... darin steht geschrieben, wie ein Punkt eingelesen wird.

    sewing schrieb:

    allerdings muss ja mein Point3D hierfür wegen operator[] default constructible sein...

    Nicht wegen std::unordered_map<...>::operator[] sondern wegen std::istream_iterator<Point3D> .



  • Sewing schrieb:

    std::ifstream inputFile{ filename };
          assert(inputFile.is_open() && !inputFile.fail());
    

    Wer hat dir denn für diesen Fall "assert" beigebracht? Mit assert kann man Programmlogik überprüfen, die IMMER wahr sein soll. Dateihandling kann auch mal fehlschlagen und hat mit programminterner Logik nichts zu tun. Wenn du im Release-Modus kompilierst, sind assert-Checks NICHT mehr enthalten!

    Siehe http://www.cplusplus.com/reference/cassert/assert/:
    "[assert] is designed to capture programming errors, not user or run-time errors"



  • und wozu taugt dann das Beispiel in den von mir referenzierten Bildern?

    verstehe den Unterschied nicht so ganz. Dort wird ja auch operator>> zweifach überladen

    und dann würde ich noch gerne wissen, wie ich statt std::copy std::transform verwenden kann. wenn ich das ersetze und als 4. parameter beispielsweise ein leeres lambda []{} verwende bekomme ich

    /usr/include/c++/7/bits/stl_algo.h:4306: error: no match for call to ‘(Parser::ExtractFromFiles()::<lambda()>) (const Point3D&)’
      *__result = __unary_op(*__first);
                  ~~~~~~~~~~^~~~~~~~~~
    


  • Was heißt leeres Lambda? Deine Lambda Funktion muss natürlich ein Parameter vom Typ const Point3D& erwarten, sonst passt das nicht.



  • Schlangenmensch schrieb:

    Was heißt leeres Lambda? Deine Lambda Funktion muss natürlich ein Parameter vom Typ const Point3D& erwarten, sonst passt das nicht.

    hatte zunächst []{} als lambda verwendet und dann

    std::transform(std::istream_iterator<Point3D>{ inputFile },
                    std::istream_iterator<Point3D>{},
                    std::back_inserter(pointClouds[cloudName]), [](const Point3D& p){});
    

    ... muss natürlich als return nen Point3D machen 🙄



  • [](const Point3D& p){};
    

    erwartet ein Point3D als Übergabeparameter und gibt nichts zurück.

    Mit Rückgabe sähe das so aus:

    [](const Point3D& p)->Point3D{return Point3D};
    

    //Edit: mit Rückgabewert muss das Lambda natürlich auch ein entsprechendes return Statement haben...



  • danke, hatte mich nur gewundert, wieso

    std::transform(std::istream_iterator<Point3D>{ inputFile }, 
                    std::istream_iterator<Point3D>{}, 
                    std::back_inserter(pointClouds[cloudName]), [](const Point3D& p){});
    

    nicht funktioniert



  • Schlangenmensch schrieb:

    Mit Rückgabe sähe das so aus:

    [](const Point3D& p)->Point3D{return Point3D};
    

    //Edit: mit Rückgabewert muss das Lambda natürlich auch ein entsprechendes return Statement haben...

    Wobei: ich gebe in der Regel den Rückgabetyp nicht explizit an, denn er ergibt sich ja sowieso aus dem return-Statement des Lambdas. (und wenn das Lambda so groß und kompliziert ist, dass es einen expliziten Returntyp braucht, ist in sehr wahrscheinlich zu viel Code im Lambda, das möglichst sehr simpel gehalten werden sollte)



  • ist ja ne simple struct um die es hier geht, mich wundert nachwie vor, wieso das lambda nicht einfach nen Point3d by reference nehmen kann und damit nichts macht, das heißt, der lambda rumpf ist leer.Dann müsste std::transform doch äquivalent mit std::copy sein. Nur das scheint nicht zu funktionieren



  • Warum sollte das gehen? Woher soll der Compiler wissen, in welchen Typ du transformieren willst?

    Du kannst auch nicht

    void foo(const int &i) { }
    ...
    some_type j = foo(i);
    

    schreiben. Das geht nicht, da muss foo schon some_type returnen. Oder erwartest du hier auch, dass aus dem "void foo" auf magische Weise ein "some_type foo" wird, das ebenfalls auf magische Weise nun den Body "return i;" bekommt?



  • leuchtet ein ; ) vielen Dank wob

    wie schätzt ihr denn das code beispiel auf den Bildern ein, die ich angehängt habe?



  • Sewing schrieb:

    wie schätzt ihr denn das code beispiel auf den Bildern ein, die ich angehängt habe?

    Wenn Du in den Dateien

    [std::string key] [struct value{std::string, std::size_t}]

    hättest, anstatt kein Key und

    [struct value{doube, double, double]

    täte der toll.



  • das war das was ich auf Seite 1 meinte. Bei mir nicht praktikabel, weil der key nicht in meinen files ist, ssondern von außerhalb kommt.

    Ich danke euch vielmals für eure Hilfe, habe wieder viel gelernt. Danke


Anmelden zum Antworten