Results 1 to 7 of 7

Thread: QT newbie: QMapIterator not showing any output, but foreach does?

  1. #1
    Join Date
    May 2012
    Posts
    3
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default QT newbie: QMapIterator not showing any output, but foreach does?

    QT4.8.1

    The following is a code snippet. It reads in a text file where each line contains json in a non-pretty-print format.

    The intent is to read in each line, extract a key called "prog_id", then store a QMap using prog_id as the key.

    Qt Code:
    1. QString filename = "/tmp/10021_sched.txt";
    2.  
    3. QFile inputfile(filename);
    4. if (!inputfile.open(QIODevice::ReadOnly))
    5. {
    6. qDebug() << "Couldn't open filename: " << filename;
    7. return false;
    8. }
    9.  
    10. QJson::Parser parser;
    11. bool ok;
    12.  
    13. QMap<QString, QString> map;
    14. QMapIterator<QString, QString> i(map);
    15. QString line;
    16. QString key;
    17.  
    18. while (!inputfile.atEnd())
    19. {
    20. // Read everything into a QMap first. The largest data file only has around 4000 lines, so not huge.
    21. line = inputfile.readLine();
    22. QVariantMap result = parser.parse(line.toLocal8Bit(), &ok).toMap(); //json parser wants QByteArray
    23. if (!ok)
    24. {
    25. printf("line %d: %s\n", parser.errorLine(), parser.errorString().toUtf8().data());
    26. return false;
    27. }
    28.  
    29. // Store each line read in from the file using prog_id as the key.
    30. //qDebug() << "progid is " << result["prog_id"];
    31. //qDebug() << "line is " << line;
    32.  
    33. key = result["prog_id"].toString();
    34.  
    35. // The next line works.
    36. qDebug() << "key is: " << key;
    37.  
    38. map[key] = line;
    39. }
    40. inputfile.close();
    41.  
    42. // Added this because the iterator didn't seem to work.
    43. i.toFront();
    44.  
    45. // This prints.
    46. printf("Starting loop\n");
    47.  
    48. while (i.hasNext())
    49. {
    50. // This doesn't print.
    51. printf("Inside loop\n");
    52. i.next();
    53. // I never get any output inside the while
    54. qDebug() << i.key() << ": " << i.value();
    55. }
    56.  
    57. // This works.
    58. foreach (QString value, map)
    59. {
    60. qDebug() << "value is: " << value;
    61. }
    To copy to clipboard, switch view to plain text mode 

    Snippet is obviously kludged together, but I'm not understanding why the while "Inside Loop" never seems to execute.
    Last edited by wysota; 31st May 2012 at 22:42. Reason: missing [code] tags

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QT newbie: QMapIterator not showing any output, but foreach does?

    What if you initialize "i" in line #42 instead of #14?
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  3. #3
    Join Date
    May 2012
    Posts
    3
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: QT newbie: QMapIterator not showing any output, but foreach does?

    That worked, but why?

    I didn't see anything in the online docs stating that the QMapIterator had to be declared after the QMap had been "filled".

  4. #4
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: QT newbie: QMapIterator not showing any output, but foreach does?

    The iterator is positioned just before the start of the map as it exists when the iterator is created. If the map is empty, the iterator's hasNext() returns false, because there is nothing to iterate over.

    STL-style iterators do not have this restriction. You can declare an STL-style iterator at any time. When you want to use it, you assign or reassign it:

    Qt Code:
    1. QMap<QString, QString> map;
    2. QMap<QString, QString>::iterator mapIt;
    3. QMap<QString, QString>::iterator mapEIt;
    4.  
    5. // ... Fill the map
    6.  
    7. // Now iterate over the contents
    8.  
    9. mapIt = map.begin();
    10. mapEIt = map.end();
    11. while ( mapIt != mapEIt )
    12. {
    13. // do something
    14. mapIt++;
    15. }
    16.  
    17. // and then you can reassign the iterators and do it again
    18.  
    19. mapIt = map.begin();
    20. mapEIt = map.end();
    21. while ( mapIt != mapEIt )
    22. {
    23. // do something else
    24. mapIt++;
    25. }
    To copy to clipboard, switch view to plain text mode 

    STL-style iterators (and presumably Java-style iterators) are invalidated as soon as the collection they are iterating over is changed, so you must take care if you are using them to change the collection. The advantage of STL iterators (IMO) are that they can be reused even when the collection changes by simply reassigning them.

    I am not sure if the QMapIterator::toFront() method can be used to reset the iterator after the map has changed or not. I don't use them. You could try your original code, but insert a call to i.toFront() at line 47 and see if that works.

    Edit: Ah, that last statement is probably incorrect. According to the docs:

    If the map is modified while a QMapIterator is active, the QMapIterator will continue iterating over the original map, ignoring the modified copy.
    So if you initialize with an empty map, the iterator continues to point to an empty map no matter what.

  5. #5
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QT newbie: QMapIterator not showing any output, but foreach does?

    Quote Originally Posted by Robert Kulagowski View Post
    That worked, but why?

    I didn't see anything in the online docs stating that the QMapIterator had to be declared after the QMap had been "filled".
    There is QMapIterator and QMutableMapIterator.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  6. #6
    Join Date
    May 2012
    Posts
    3
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: QT newbie: QMapIterator not showing any output, but foreach does?

    Quote Originally Posted by d_stranz View Post
    The iterator is positioned just before the start of the map as it exists when the iterator is created. If the map is empty, the iterator's hasNext() returns false, because there is nothing to iterate over.

    <snip>

    So if you initialize with an empty map, the iterator continues to point to an empty map no matter what.
    That's the secret sauce that I was missing. It makes perfect sense now, but doesn't that mean that the QMapIterator has to be inline with the main body of the code rather than in a header somewhere? (Assuming that I want to continue using java style iterators)

  7. #7
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: QT newbie: QMapIterator not showing any output, but foreach does?

    ...doesn't that mean that the QMapIterator has to be inline with the main body of the code rather than in a header somewhere?
    Yes, and declared at the point of use when the map is complete. Wysota suggests QMutableMapIterator which name implies a different behaviour. An iterator of that type may allow you to declare it in a header.

    Iterators are cheap, though - create them on the stack, use them, throw them away. If you're thinking you are optimizing by declaring a member variable, you aren't really.

Similar Threads

  1. Day showing wrongly in thread list in NewBie
    By karthic in forum General Discussion
    Replies: 1
    Last Post: 29th April 2012, 14:06
  2. lifetime of foreach
    By BalaQT in forum Newbie
    Replies: 4
    Last Post: 4th March 2010, 15:55
  3. bad behaviour of QMapIterator
    By zorro68 in forum Qt Programming
    Replies: 2
    Last Post: 14th February 2008, 22:16
  4. Showing the output from cmake on my widget
    By jsmax in forum Qt Programming
    Replies: 3
    Last Post: 18th May 2007, 20:17
  5. Replies: 4
    Last Post: 10th May 2006, 22:37

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.