File Line Reader

Iterating through an input file is something I find myself doing in almost every project I write. It is incredibly boilerplate code, but can be difficult to generalise as you wish to execute custom code within a loop.

The two file line reader codes here are therefore a set of macros which generalise this boilerplate code and make it simple to execute such boilerplate loops.

Warning!

Be careful when using these commands

They are somewhat hacky macros which wrap around custom code. This means you need to be exceptionally careful:

  • Compilation error messages can become garbled and confusing if arising from code piped into the macro. Read through the error logs carefully to isolate the problem.

  • The following variable names will temporarily go out of scope as they are re-utilised by the code (they re-enter scope when the block ends - note that this means that you do not need to worry about the macros overwriting your other variables, which is some comfort):

    • std::string FILE_LINE

    • std::vector<std::string> FILE_LINE_VECTOR

  • Use parentheses (), not curly braces {} around the code block.

  • After the close-paren, remember a semi-colon.

  • They are not within the JSL namespace, annoyingly

Macros

forLineIn(macroFileName, ...)

Iterates through the file line-by-line (until EOF), saving the current line to std::string FILE_LINE

Parameters:
  • macroFileName – The target file to search through

  • ... – A custom block of C++ code which executes on every line of the file. You may use any externally defined variables within this block.

Returns:

Current line is accessible via the variable std::string FILE_LINE. If the file does not exist, throws an exit(1) command

forLineVectorIn(macroFileName, token, ...)

Iterates through the file line-by-line (until EOF), saving the current line to std::string FILE_LINE, and then tokenises it using split(), based on the chosen delimiter, saving it to std::vector<std::string>> FILE_LINE_VECTOR

Parameters:
  • macroFileName – The target file to search through

  • token – The delimiter used to break up FILE_LINE into FILE_LINE_VECTOR

  • ... – A custom block of C++ code which executes on every line of the file. You may use any externally defined variables within this block.

Returns:

Current line is accessible via the variable std::string FILE_LINE and std::vector<std::string>> FILE_LINE_VECTOR. If the file does not exist, throws an exit(1) command

Example Usage

If the file sonnet116.txt contains the full text of the relevant Shakespearean Sonnet, and we wished to find the 4th word of any line more than 40 characters long:

//sonnet.cpp

#include <iostream>
#include "JSL.h"
int main(int argc, char * argv[])
{
 std::string fileName = "sonnet116.txt";
 forLineVectorIn(fileName,' ',
   if (FILE_LINE.length() > 40)
   {
          std::cout << FILE_LINE_VECTOR[3] << std::endl;
   }
 );
}

When run:

>./sonnet
tempests
although
fool,
sickle's
with
out

Note that because we defined “words” to be delineated only by spaces, we retained the comma after “fool”. We could add further code into the macro to remove this, if we desired.