Qt/C++ - jak poprawnie zwrócić wartość z funkcji ?

0

Niby temat prosty ale mam dylemat.

Napisałem poniższą funkcję, której zadaniem jest wczytać plik JSON i następnie ta funkcja ma go zwrócić

QJsonDocument SettingsFile::ReadSettings()
{
    QFile jsonFile;

    jsonFile.setFileName(QString("settings.json"));
    
    if(!jsonFile.open(QIODevice::ReadOnly | QIODevice::Text)){
        qDebug()<< "nie znaleziono pliku";
    }
    else{
        QByteArray data;
        data = jsonFile.readAll();
        
        jsonDocument = QJsonDocument::fromJson(data);
        
        return jsonDocument; //wydaje mi się, że dobrze zwracam obiekt
    }
//ale kompilator zwraca mi uwagę, że tutaj powinienem ten obiekt zwrócić więc jak to zrobić dobrze ?
}

Dodałem komentarze do kodu aby zobrazować w czym mam problem. Czy ktoś udzieli mi prawidłowej odpowiedzi ?

EDIT:
Dlaczego o to pytam ? Bo przypadki są dwa

  1. znalezienie pliku
  2. nie znalezienie pliku

wariant 1 - jak nie znajdzie pliku, to jak umieszczę return jak sugeruje kompilator, to funkcja zwróci pustego jsona
wariant 2 - znalazłem plik i funkcja ma zwrócić tylko to co znalazła, pustego obiektu nie chcę zwracać, bo po co ?

0

https://doc.qt.io/qt-5.15/qjsondocument.html#fromJson

Wygląda że poprawnie używasz, ale ja bym jeszcze sprawdził czy faktycznie poprawnie sparsowało, bo:

Returns a valid (non-null) QJsonDocument if the parsing succeeds. If it fails, the returned document will be null, and the optional error variable will contain further details about the error.

0

chodzi mi o tą żółtą uwagę

screenshot-20211106211812.png

0

Wydaje mi się że w niektórych przypadkach ta metoda zwrócić ci może nulla. This function has no way of reporting errors; returning an empty QByteArray can mean either that no data was currently available for reading, or that an error occurred.

0

@.andy: czy o to ci chodziło ?

QJsonDocument SettingsFile::ReadSettings()
{
    QFile jsonFile;

    jsonFile.setFileName(QString("settings.json"));

    if(!jsonFile.open(QIODevice::ReadOnly | QIODevice::Text)){
        qDebug()<< "nie znaleziono pliku";
    }
    else{
        QByteArray data;
        data = jsonFile.readAll();

        jsonDocument = QJsonDocument::fromJson(data);

        if(!jsonDocument.isNull()){
            return jsonDocument;
        }
        else{
            qDebug()<< "dupa z prasowania";
        }
    }
}
0

A ja Bracie @zkubinski wpierw przysiadłbym do deski i zastanowił się, czego tak naprawdę potrzebuję; readSettings() które wyciąga QJsonDocument sugeruje, iż nie o owego jsona ci chodzi, ino o jakieś dane z niego. Czemu zatem nie zmodyfikować funkcji na szukającą owych danych? Inna jeszcze sprawa, czy koniecznie potrzebujesz jsona, może zwykły QSettings załatwi sprawę?

0

Tutaj tez możesz mieć nulla data = jsonFile.readAll(); Nie wiem jak to się pisze teraz w Qt ale pewnie warto rzucić jakimś wyjątkiem w stronę uzytkownika.

1

Taka mała podpowiedź - oto jak wczytać .jsona z pliku z uwzględnieniem, iż coś może się nie udać; stosuję tą metodę w moim programie Mech Designer

            QJsonParseError error;
            QJsonObject json = QJsonDocument::fromJson(file.readAll(), &error).object();
            file.close();
            if (json.isEmpty())
            {
//to jsonParseError wyświetla QMessageBoxa z tekstem co i gdzie jest zrypane. Baaaardzo mi to ułatwiło pracę z niechlujnie stworzonymi .jsonami
                Global::jsonParseErrorMessage(file.fileName(), QString::number(error.offset), error.errorString());
                continue;
            }
0

mój json wygląda tak

{
    "settings": {
        "data-from": {
            "dept": "Bankowy"
        },
        "network": {
            "connect": "Komputer lokalny",
            "ipaddr": "127.0.0.1",
            "login": "login",
            "password": "fc8dda7308bc24f87920c0af3b39397"
        }
    }
}
0
zkubinski napisał(a):

no właśnie patrzę na opis klasy QJsonParseError i opis jest tak krótki, że nie wiem jak się do niego zabrać...

Bo i nie ma w tej klasie jakieś nie wiadomo jakiej filozofii. Po prostu, używając QJsonDocument QJsonDocument::fromJson(const QByteArray &json, QJsonParseError *error = nullptr) można jako 2 parametr podać owego QJsonParseErrora, i jeśli parsowanie się nie powiedzie to z tego obiektu wyczytasz co poszło nie tak.

6

Podstawa C++: jeśli funkcja deklaruje, że coś zwraca, to ma to coś zwracać, inaczej to UB1.

Jeśli QJsonDocument nie potrafi opisać twojego zamiaru, to znaczy, że nie jest poprawnym typem zwracanym. Zapewne chcesz std::optional<QJsonDocument> (lub w przyszłości std::expected), i chcesz zwracać pustego optionala jeśli wczytanie się nie powiedzie. Przy czym wiele typów Qt, w tym QJsonDocument oferują koncepcję null obiektu, i możesz po prostu zwrócić pusty QJsonDocument, a potem sprawdzić na wyniku isNull().

1 za wyjątkiem main()

1

widzę że zakręcamy pętle z przed ilu 4-5 miesięcy? piszesz obsługę jsona w qt ile już 1,5 roku?
I zrobię to co wtedy zrobiliśmy co i pewnie i tak zlejesz. Czyli że masz wreszcie nauczyć się c++ i qt z kursów.
https://isocpp.org/
https://www.onlinebooksreview.com/articles/best-qt-books
https://en.cppreference.com/w/cpp/language/return

w sumie sam nie wiem po co po raz n-ty mówię o powrocie do podstaw c++.
I kwestia plików ini. to nie wiem co ty masz za kolegów co ci mówią o jakiś przestarzałych ini.

0

@revcorey:

widzę że zakręcamy pętle z przed ilu 4-5 miesięcy? piszesz obsługę jsona w qt ile już 1,5 roku?

nie rozumiem twojego czepialstwa "co, ile i dlaczego" - to moje prywatne życie ale mniej więcej odpowiem, chociaż wątpię, że na swój programistyczny sagan zrozumiesz, a wydaje mi się, że jak masz wysokie ego, to powinieneś zrozumieć - mam mnóstwo zajęć i muszę ogarnąć wiele rzeczy, w tym kilka życiowych spraw, więc jest to nie tylko programowanie i jak mam wolny czas to siadam i wracam do tematu - zbyt skomplikowane dla ciebie ? Jeżeli tak, to nie mój problem, to ty masz problem.

skoro odpowiadam na wątek, to chciałbym się zwrócić z jednym pytaniem do @MasterBLB

klasa QJsonParseError zwraca offset jak to rozumieć ? Czy to jest numer pozycji na której brakuje odpowiedniego znaku aby JSON był uznany za prawidłowy ? Kilka przykładów poniżej

163 "unterminated object"
229 "unterminated object"

1
zkubinski napisał(a):

skoro odpowiadam na wątek, to chciałbym się zwrócić z jednym pytaniem do @MasterBLB

klasa QJsonParseError zwraca offset jak to rozumieć ? Czy to jest numer pozycji na której brakuje odpowiedniego znaku aby JSON był uznany za prawidłowy ? Kilka przykładów poniżej

163 "unterminated object"
229 "unterminated object"

Generalnie tak, przy czym offset to nie jest numer linii, tylko indeks znaku gdzie wykryty został błąd - w zdaniu "Ala ma kota" offset 'k' to 7. Ja używałem tego w taki sposób, iż błędnego .jsona otwierałem w Notepad++, po czym zapodawałem ctrl+g, nastawiałem radio button na 'Offset', i w pole edycyjne wpisywałem wartość jaką zwrócił parse error.
Miej na uwadze iż podawanie tego offsetu przez QJsonParseError nie zawsze jest perfekcyjnie precyzyjne, np. w najczęściej spotykanym przeze mnie błędzie braku przecinka separującego kolejne obiekty pokazywał mi linijkę niżej.

1 użytkowników online, w tym zalogowanych: 0, gości: 1