Search code examples
c++node.jsnode.js-addon

Looping over file, only get one line


Say we have a text file with this contents:

dogs
cats
bears
trees
fish
rocks
sharks

these are just words separated by newline chars. I am trying to create a Node.js addon. The Addon will read through a file and replacing matching lines with a blank line. Say I pass my program a regex that matches /trees/. If I pass the file to my C++ program it will read + write to the file, and result in:

dogs
cats
bears
   
fish
rocks
sharks

Right now, the problem is it's not looping through all the lines in the file. I get the feeling that's opening the file in append mode and therefore just starting at the end of the file? I can't tell. Anyway, I want to edit the file in place, not truncate and re-write or replace the whole file, because this will interrupt processes which are tailing the file.

Here's the code:

#include <nan.h>
#include <fstream>
#include <sstream>
#include <string>
#include <iostream>

using namespace std;

void Method(const Nan::FunctionCallbackInfo<v8::Value>& info) {
  info.GetReturnValue().Set(Nan::New("world").ToLocalChecked());
}

void Init(v8::Local<v8::Object> exports) {

fstream infile("/home/oleg/dogs.txt");

if(infile.fail()){
  cerr << " infile fail" << endl;
  exit(1);
}

int pos = 0;
string line;

int count = 0;
while (getline(infile, line)){    

// we only seem to loop once, even though the file has 7 or 8 items 

    count++;
    long position = infile.tellp();
    cout << "tellp position is " << position << endl;
    string str(line);
    int len = str.length();

    cout << " => line contains => " << line << endl;
    cout << " line length is " << len << endl;

    std::string s(len, ' ');  // create blank string of certain length

    infile << s;   // write the string to the current position

    pos = pos + len;
    cout << "pos is " << pos << endl;


}


 cout << " => count => " << count << endl;
infile.close();


  exports->Set(Nan::New("hello").ToLocalChecked(),
               Nan::New<v8::FunctionTemplate>(Method)->GetFunction());
}

NODE_MODULE(hello, Init)

To compile the code you might need to use Node.js tooling, which is

node-gyp rebuild

I am a C++ beginner and I think this can be figured out without compiling/running the code.


Solution

  • To answer your question on why you only read one line of the input file:

    Your first write to the file likely sets the eofbit on the stream, so the second getline() attempt will think it has no more to read.

    The comment from @RSahu describes the simplest way to do this for text files.