Results 1 to 16 of 16

Thread: remove specific line using readLine()

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Feb 2019
    Posts
    7
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default remove specific line using readLine()

    Hi to all.

    I want to find a specific string between lines to remove it, I'm usign readLine() to read a text with TextStream.
    for example:

    Qt Code:
    1. QTextStream text(&file);
    2. while(!text.atEnd()){
    3. vectorData[ii] = text.readLine();
    4. ...
    5. ii++;
    6. }
    To copy to clipboard, switch view to plain text mode 

    the read is something like:

    Banana
    Kiwi
    Apple
    Banana
    Banana
    Apple
    Mango
    Apple
    Mango

    so, I want to remove the Apple line just after the Banana line.

    Banana
    Kiwi
    Apple
    Banana
    Banana
    Apple <--- This one
    Mango
    Apple
    Mango

    First I need to locate the specific line, I tried:

    Qt Code:
    1. if(vectorData[ii].contains("Banana\0Apple")) // Do something
    To copy to clipboard, switch view to plain text mode 

    but didn't work.
    Qt Code:
    1. "Banana\nApple"
    To copy to clipboard, switch view to plain text mode 
    and
    Qt Code:
    1. "Banana\n\rApple"
    To copy to clipboard, switch view to plain text mode 
    neither. I can't use readAll() because the rest of the code breaks down. Must be taken into account every time I read the text, all the lines are in different position (the textfile is randomly modified). Thanks, I'm super newbie.

  2. #2
    Join Date
    Jul 2008
    Location
    Germany
    Posts
    503
    Thanks
    11
    Thanked 76 Times in 74 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: remove specific line using readLine()

    Hi,

    as the docs say:
    The returned line has no trailing end-of-line characters ("\n" or "\r\n")
    , and readLine returns only one line, so you can't use checks like the ones you tried.

    Just set a variable when you find a "Banana" (and unset it if you find something else). Then when you find "Apple" check if the variable is set.

    You can also check if the previous element (vectorData[ii-1]) is "Banana" when you find an "Apple", but you will have to take care of some cases, e.g. Apple being the first entry.

    Ginsengelf

  3. #3
    Join Date
    Feb 2019
    Posts
    7
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default Re: remove specific line using readLine()

    Thank you Ginsengelf for your clear reply. The solution was very simple, but I forgot to specify some extra conditions.

    The banana-apple sequence can happen many times but I just needed to replace it in the last event.

    Banana
    Apple
    ...
    Banana
    Apple
    ...
    Banana
    Apple <-This one
    end

    So, based on your suggestion the solution was:

    Qt Code:
    1. QTextStream text(&file);
    2. int line = 0;
    3. while(!text.atEnd()){
    4. vectorData[ii] = text.readLine();
    5. if((vectorData[ii].contains("Apple") && vectorData[ii-1].contains("Banana")){
    6. line = ii;
    7. }
    8. QString Fruit = "Grape";
    9. conflict = vectorData[line].replace(0, line, Fruit); // conflict is a QString global variable
    10. ...
    11. ii++;
    12. }
    To copy to clipboard, switch view to plain text mode 

  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: remove specific line using readLine()

    How do you know that "vectorData" will be large enough to hold all the lines in the file? You keep incrementing "ii" with every new line and assign the string to "vectorData[ii]". What happens if you have vectorData sized to hold 20 items, and there are 21 lines in the file?
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  5. #5
    Join Date
    Feb 2019
    Posts
    7
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default Re: remove specific line using readLine()

    I think the condition "!text.atEnd()" in the while loop deals with, but maybe I'm not understanding the question well. Anyway, I have not had any problems with that.

    I did not add the solution to the extra condition that I mentioned earlier because it is more complex than bananas and apples thing and there are more functions involved in the process. But if someone has a similar doubt I can show my solution.

  6. #6
    Join Date
    Jul 2008
    Location
    Germany
    Posts
    503
    Thanks
    11
    Thanked 76 Times in 74 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: remove specific line using readLine()

    Hi, d_stranz meant that you store each line in vectorData (which looks like it has a fixed size), but what happens if you have a really large file with loooots of lines?

    Ginsengelf

  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: remove specific line using readLine()

    @Ginsengelf - Exactly. If there is even one more line in the file than the size of the vectorData array, then the program can crash. So:

    it is more complex than bananas and apples thing
    if we can find a potentially fatal error in the simplified code you posted, then it might be a good idea to understand what the two of us are talking about.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  8. #8
    Join Date
    Feb 2019
    Posts
    7
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default Re: remove specific line using readLine()

    Now I understand, both of you are right. If the size of the text is very large the program crashes and it's a really big problem for what I'm trying to doing.
    I said that the code was modified randomly to simplify that I am working with different files with similar coding but different location of their parameters. To be more precise I am decoding gerber files to generate their corresponding image, supporting me with openCV libraries. If it were not for your question I would not have noticed that the files that exceed a thousand lines cause conflict because I had only been working with a few compact files (six different gerber files with an extension of 100-800 lines). You make a good point!.
    Now I'm trying to enlarge the vectorData size but it only causes the program to be slower and the problem persists.
    What do you recommend for these cases? Concatenation?
    Thanks for your attention.

  9. #9
    Join Date
    Mar 2008
    Location
    Kraków, Poland
    Posts
    1,536
    Thanked 284 Times in 279 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: remove specific line using readLine()

    1. What vectorData definition looks like ?
    2. Do you want to delete lines from a file or from a vector?

  10. #10
    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: remove specific line using readLine()

    Now I'm trying to enlarge the vectorData size but it only causes the program to be slower and the problem persists.
    In addition to what Lesiok asks, do you actually need to keep all the data that you read from the file? Or can you convert the gerber instructions into the corresponding image pixels on the fly? If you need to discard lines from the gerber file, but the decision to discard depends on some context (eg. a series of lines must match a pattern, otherwise the lines are OK), then you could implement something that accumulates only a small number of lines until you can make the "keep or discard" decision. If the decision is keep, you convert what you have to pixels, other wise you discard, but in either case you can empty the vector out.

    Maybe this is also an oversimplification and won't work. If you do need to keep all the lines, maybe you can read the whole file into a QByteArray, parse it into individual lines and keep a index to the byte position of the start of each line. When you come to a line you don't want, you don't store the index (or change it to a negative number to act as a flag while still being able to determine how long each line is). (Length of line "n" is the abs(offset) of line "n + 1" minus abs(offset) of line "n"). QByteArray can easily handle sizes in the megabytes.

    In any case, you can avoid a size restriction on "vectorData" by defining it as either a QStringList or a QVector< QString >. As you read each line, you call the push_back() method of either class to append the new line to the end of the collection. Both classes will grow the size automatically when needed to add more lines.
    Last edited by d_stranz; 9th February 2019 at 18:33.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  11. #11
    Join Date
    Feb 2019
    Posts
    7
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default Re: remove specific line using readLine()

    Hi Lesiok.

    1. What vectorData definition looks like ?
    vectorData is a QString array and it is initialized:

    Qt Code:
    1. QString vectorData[100000]
    To copy to clipboard, switch view to plain text mode 

    I'm also working with a set of variables that stores a specific parameter like:

    Qt Code:
    1. QString X[10000], Y[10000], infoNumber[10000], infoD[10000], infoShape[100]
    To copy to clipboard, switch view to plain text mode 
    ... etc, etc.

    The array size is large because I'm trying to get the right amount for read large files.

    So vectorData is a line and column reader of all the text, and the rest of the variables mentioned are column reader from specific lines section of the text to extract a definited parameter. To put it clearly I give the example of how I get the coordinates in X and I list each value obtained

    Qt Code:
    1. void MainWindow::on_pushButtonCargarGerber_clicked()
    2. {
    3. QString nombreArchivo = QFileDialog::getOpenFileName(this, tr("Open File"), QDir::currentPath(), tr("Files (*.grb *.txt)"),0,QFileDialog::DontUseNativeDialog);
    4. QFile archivo(nombreArchivo.toUtf8().constData());
    5. QTextStream Texto(&archivo);
    6. int ii = 0;
    7. int jj = 0;
    8. if(!archivo.open(QIODevice::ReadOnly | QFile::Text)){
    9. qDebug()<<"No se puede abrir " << nombreArchivo;
    10. exit(1);
    11. }
    12. else{
    13. QString separatorX = "X";
    14. ...
    15. while (!Texto.atEnd()){
    16. vectorData[ii] = Texto.readLine();
    17. int posicionX = vectorData[ii].indexOf(separatorX);
    18. ...
    19. int tamanioFila = vectorData[ii].length();
    20. // ************************** COORDENADAS XY ************************** //
    21. int tamXY;
    22. if(F2.toInt()==4) tamXY=18; if(F2.toInt()==5) tamXY=20;
    23. if(tamanioFila == tamXY){
    24. QString temporal = vectorData[ii].mid(0, posicionX+1);
    25. if(temporal==separatorX){
    26. temporal.insert(0, QString::number(jj+1));
    27. infoNumero[jj] = temporal;
    28. int c;
    29. if(jj>=0 && jj<9) c = 1;
    30. else if(jj>=9 && jj<99) c = 2;
    31. else if(jj>=99 && jj<999) c = 3;
    32. else c = 4;
    33. temporal = infoNumero[jj].mid(0, c);
    34. infoNumero[jj] = temporal;
    35. // X
    36. temporal = vectorData[ii].mid(posicionX+1, posicionY-1);
    37. infoX[jj] = temporal;
    38. // Y
    39. ...
    40. jj++;
    41. }
    42. }
    43. ii++;
    44. }
    45. }
    46. }
    To copy to clipboard, switch view to plain text mode 

    --

    2. Do you want to delete lines from a file or from a vector?
    In the first instance I thought that removing a particular line from the vector would be a good idea but it is not, now I am using a Ginsengelf advices to locate and ignore a specific line.

    --

    At the moment, the program looks like:

    imageGerberProgram.jpg
    Last edited by jasif; 9th February 2019 at 19:18.

  12. #12
    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: remove specific line using readLine()

    QString vectorData[100000];
    QString X[10000], Y[10000], infoNumber[10000], infoD[10000], infoShape[100];
    Change all of these to QStringList or QVector<QString> and you will never have to worry about the size being too small.

    Qt Code:
    1. void MainWindow::on_pushButtonCargarGerber_clicked()
    2. {
    3. QString nombreArchivo = QFileDialog::getOpenFileName(this, tr("Open File"), QDir::currentPath(), tr("Files (*.grb *.txt)"),0,QFileDialog::DontUseNativeDialog);
    4. QFile archivo(nombreArchivo.toUtf8().constData());
    5. QTextStream Texto(&archivo);
    6. int ii = 0;
    7. int jj = 0;
    8. if(!archivo.open(QIODevice::ReadOnly | QFile::Text)){
    9. qDebug()<<"No se puede abrir " << nombreArchivo;
    10. exit(1);
    11. }
    12. else{
    13. QString separatorX = "X";
    14. ...
    15. vectorData.clear(); // First easy change - ensure vectors start empty
    16. infoNumeral.clear();
    17. infoX.clear();
    18. infoY.clear();
    19. // ... etc.
    20.  
    21. while (!Texto.atEnd()){
    22. vectorData.push_back( Texto.readLine() ); // Second easy change: vectorData will grow if needed
    23. int posicionX = vectorData[ii].indexOf(separatorX);
    24. ...
    25. int tamanioFila = vectorData[ii].length();
    26. // ************************** COORDENADAS XY ************************** //
    27. int tamXY;
    28. if(F2.toInt()==4) tamXY=18; if(F2.toInt()==5) tamXY=20;
    29. if(tamanioFila == tamXY){
    30. QString temporal = vectorData[ii].mid(0, posicionX+1);
    31. if(temporal==separatorX){
    32. temporal.insert(0, QString::number(jj+1));
    33. infoNumero.push_back( temporal ); // Next change
    34. int c;
    35. if(jj>=0 && jj<9) c = 1;
    36. else if(jj>=9 && jj<99) c = 2;
    37. else if(jj>=99 && jj<999) c = 3;
    38. else c = 4;
    39. temporal = infoNumero[jj].mid(0, c);
    40. infoNumero[jj] = temporal;
    41. // X
    42. temporal = vectorData[ii].mid(posicionX+1, posicionY-1);
    43. infoX.push_back( temporal ); // Next change
    44. // Y
    45. ... // etc. for decoding other parameters
    46. jj++;
    47. }
    48. }
    49. ii++;
    50. }
    51. }
    52. }
    To copy to clipboard, switch view to plain text mode 

    You are using "jj" to index several arrays - are each of these arrays exactly matched (in other words, when you decode a line, if it contains "X" will it also contain Y, infoNumber, and infoD? If not, then these vectors will not be synchonized - the entries will refer to different lines, so you can't say X[n] matches with Y[n].

    If each line contains all of these parameters, then you would be better off using a struct instead of separate vectors:

    Qt Code:
    1. struct ParameterLine
    2. {
    3. QString infoX;
    4. QString infoY;
    5. QString infoNumber;
    6. QString infoD;
    7. };
    8.  
    9. QVector< ParameterLine > parameterLines;
    10.  
    11. // ...
    12. if(temporal==separatorX){
    13. ParameterLine currentLine;
    14.  
    15. temporal.insert(0, QString::number(jj+1));
    16. currentLine. infoNumero = temporal; // Next change
    17. int c;
    18. if(jj>=0 && jj<9) c = 1;
    19. else if(jj>=9 && jj<99) c = 2;
    20. else if(jj>=99 && jj<999) c = 3;
    21. else c = 4;
    22. temporal = currentLine.infoNumero.mid(0, c);
    23. currentLine.infoNumero = temporal;
    24. // X
    25. temporal = vectorData[ii].mid(posicionX+1, posicionY-1);
    26. currentLine.infoX = temporal; // Next change
    27. // Y
    28. ... // etc. for decoding other parameters
    29.  
    30. parameterLines.push_back( currentLine );
    31. jj++;
    32. }
    33.  
    34. // And you can retrieve any field using parametersLines[ n ].infoX, etc.
    To copy to clipboard, switch view to plain text mode 

    One more trick: instead of the multiple if / else statements to determine the number of digits in jj, try this:

    Qt Code:
    1. int c= 1 + int( std::log10( float( jj ) ) );
    To copy to clipboard, switch view to plain text mode 
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

Similar Threads

  1. Read a file after a specific line
    By kahlenberg in forum Qt Programming
    Replies: 4
    Last Post: 20th September 2018, 19:35
  2. To jump to a specific line in a textedit
    By aaditya190 in forum Newbie
    Replies: 4
    Last Post: 21st November 2013, 11:51
  3. How do I set a QTextEdit to a specific line by line number?
    By Coolname007 in forum Qt Programming
    Replies: 8
    Last Post: 1st February 2013, 06:18
  4. Replies: 1
    Last Post: 30th March 2012, 16:35
  5. Read a specific line from a file
    By rleojoseph in forum Qt Programming
    Replies: 11
    Last Post: 21st March 2011, 12:58

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.