1

I would like to know how can I search a line by its text on a textfile and delete it. After looking at this topic-->Delete specific line from a text file? I found out this code in C#:

string line = null;
string line_to_delete = "the line i want to delete";

using (StreamReader reader = new StreamReader("C:\\input")) {
    using (StreamWriter writer = new StreamWriter("C:\\output")) {
        while ((line = reader.ReadLine()) != null) {
            if (String.Compare(line, line_to_delete) == 0)
                continue;

            writer.WriteLine(line);
        }
    }
}

I tried to convert it to something like this in C++/CLI:

System::String^ txtfile = L"C:\\Users\\acer\\Desktop\\aaa.txt";
 String^ line = nullptr;
 String^ line_to_delete = "dasdasdasda";

                    using (StreamReader ^reader = gcnew StreamReader(gcnew String(txtfile)) {
                        using (StreamWriter ^writer = gcnew StreamWriter(gcnew String(txtfile),true) {
                         while ((line == reader->ReadLine()) != nullptr) {
                            if (String.Compare(line, line_to_delete) == 0)
                            continue;

                    writer->WriteLine(line);
            }
        }
    }

but since I'm still a newbie I didn't do it right. Please notice that I did not create any temporary file, I just want to read my textfile, detect the line that says "dasdasdasda" and delete it. Can someone tell what I did wrong when converting from C# to C++/CLI?

Community
  • 1
  • 1
sparrow.
  • 101
  • 8

2 Answers2

1

I've never really worked with .Net but I heard that you can mix both native c++ in the Visual Studio IDE so here is my shot for your problem.

/*
 * findLine.cpp
 */

#include <iostream>
#include <fstream>
#include <vector>
#include <string>

using namespace std;

void LineDeleter( string fileName, string line_to_delete )
{
  fstream myFile( fileName.c_str(), ios::in );  // Read from file.
  vector<string> strArray;  // Where we copy line by line.
  // Retrieve line by line.
  while( myFile.good() )
    {
      char buffer[256];
      myFile.getline( buffer, 256 );
      if( line_to_delete != buffer )
    strArray.push_back( buffer );
    }
  myFile.close();

  // Writing session.
  myFile.open( fileName.c_str(), ios::out | ios::trunc );
  for( auto iter = strArray.begin(); iter != strArray.end(); iter++ )
    {
      myFile << *iter << endl;;
      cout << *iter << endl;
    }
  myFile.close();

}
int main( int argc, char **args )
{
  LineDeleter( "text.txt", "(c)2013 All Rights Reserved." );
}

Basicly LineDeleter will take two arguments, the filename of the text file and the string of the line to delete. This will delete all lines matching the line to delete.

For new request: Concerning the new request about deleting the line containing a substring here's the code:

void deleteContainingSubString(  string fileName, string subString )
{
  fstream myFile( fileName.c_str(), ios::in );  // Read from file.
  vector<string> strArray;  // Where we copy line by line.
  // Retrieve line by line.
  while( myFile.good() )
    {
      char buffer[256];
      myFile.getline( buffer, 256 );
      string buffer02 = buffer;
      if( buffer02.find( subString ) == string::npos )
    strArray.push_back( buffer );
    }
  myFile.close();

  // Writing session.
  myFile.open( fileName.c_str(), ios::out | ios::trunc );
  for( auto iter = strArray.begin(); iter != strArray.end(); iter++ )
    {
      myFile << *iter << endl;;
      cout << *iter << endl;
    }
  myFile.close();

}

Edit 1: I optimize the code a bit. Edit 2: Added the code concerning the new request.

  • Why would you, in 2013, use `std::istream::getline` with a char array instead of `std::getline` with a string reference? Especially if you then put the results into a string? – Medinoc Aug 26 '13 at 08:02
  • @Medinoc Well to be honest, I don't know that. Then again, I think the algorithm above is far from perfect. – ComputrScientist Aug 27 '13 at 00:49
  • @ComputrScientist What if I wanted to check if a line contains a specific string and delete the whole line if it does? For example if there is a line that says "asd 123", I would like for LineDeleter to search for the string "asd" and when it detected the line "asd 123"or any line that contained the string "asd", it would delete the whole line. – sparrow. Aug 27 '13 at 02:39
  • @sparrow. Hello again, I added a new code that will delete the line containing a substring. Test it and kindly report back if it works. – ComputrScientist Aug 27 '13 at 04:33
  • @ComputrScientist Thank you once again, that worked out nicely. – sparrow. Aug 27 '13 at 04:42
1

The equivalent to the C# using statement is to use the reference type without the ^. This makes it use RAII.

String^ line = nullptr;
String^ line_to_delete = "the line i want to delete";

StreamReader reader("C:\\input");
StreamWriter writer("C:\\output");

while ((line = reader.ReadLine()) != nullptr) {
    if (String::Equals(line, line_to_delete))
        continue;

    writer.WriteLine(line);
}

A few things to note:

  • You can only do this in C++/CLI when you create the object yourself: You can't use it with the return value from another method, like you can with using in C#.
  • Without the ^ on the variable, we use . to call methods, rather than ->.
  • I corrected your use of String::Compare to be String::Equals. Compare should be used only for sorting; for testing equality, use Equals.
David Yaw
  • 27,383
  • 4
  • 60
  • 93
  • Thanks, but unfortunately that didn't work, It gave me 24 errors. Some of them on my project's .cpp file and some of them on my Form1.h file, where it said StreamReader and StreamWriter were undeclared identifiers. I guess I'll use the method posted above by ComputrScientist. – sparrow. Aug 26 '13 at 19:31
  • I had an extra `)` in the declaration of reader & writer, sorry about that. Don't forget the `using namespace System::IO;` at the top of your file. – David Yaw Aug 26 '13 at 19:48