0

I have hit a brick wall trying to format one of my files. I have a file that I have formatted to look like this:

 0          1          2          3          4          5
 0.047224   0.184679  -0.039316  -0.008939  -0.042705  -0.014458
-0.032791  -0.039254   0.075326  -0.000667  -0.002406  -0.010696
-0.020048  -0.008680  -0.000918   0.302428  -0.127547  -0.049475
 ... 
 6          7          8          9          10         11
 [numbers as above]
 12         13         14         15         16         17
 [numbers as above]
 ...

Each block of numbers has exactly the same number of lines. What I am trying to do is basically move every block (including the headers) to the right of the first block so in the end my output file would look like this:

 0          1          2          3          4          5              6         7         8        9          10         11     ...
 0.047224   0.184679  -0.039316  -0.008939  -0.042705  -0.014458   [numbers]    ...
-0.032791  -0.039254   0.075326  -0.000667  -0.002406  -0.010696   [numbers]    ...
-0.020048  -0.008680  -0.000918   0.302428  -0.127547  -0.049475   [numbers]    ...
 ...

So in the end I should basically get a nxn matrix (only considering the numbers). I already have a python/bash hybrid script that can format this file exactly like this BUT I've switched the running of my code from Linux to Windows and hence cannot use the bash part of the script anymore (since my code has to be compliant will all versions of Windows). To be honest I have no idea how to do it so any help would be appreciated!

Here's what I tried until now (it's completely wrong I know but maybe I can build on it...):

 void finalFormatFile()
 {
 ifstream finalFormat;
 ofstream finalFile;
 string fileLine = "";
 stringstream newLine;
 finalFormat.open("xxx.txt");
 finalFile.open("yyy.txt");
 int countLines = 0;
 while (!finalFormat.eof())
 {
     countLines++;
     if (countLines % (nAtoms*3) == 0) 
     {
       getline(finalFormat, fileLine);
       newLine << fileLine;
       finalFile << newLine.str() << endl;
     }
     else getline(finalFormat, fileLine);
 }
 finalFormat.close();
 finalFile.close();
}
JavaNewb
  • 35
  • 1
  • 9
  • What is the `nAtoms` variable ? The number of lines without the header (1, 2, 3, ...) ? – Thomas W. Sep 19 '16 at 21:25
  • yes exactly, for example if nAtoms is 30 then the number of lines without the header will be 90 (since every atom has 3 spatial coordinates - this is what the numbers correspond to) so in the end I'd get a 90x90 matrix (excluding the header). – JavaNewb Sep 19 '16 at 21:27
  • 2
    Off topic: `while (!finalFormat.eof())` is a common error. Read more here: http://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong – user4581301 Sep 19 '16 at 21:32
  • What is the purpose of << endl in your newLine output? The endl modifier creates a new line. From your explanation it looks like you wanted to concatenate lines. Did you try to replace endl with " " or "\t" or whatever is your column separator? And one more thing: When you say that something doesn't work, a brief description of what did not work could be really helpful. For example: "I get line breaks where I do not expect them." – Victor Havin Sep 19 '16 at 21:37
  • I know about the .eof() error and I've been meaning to change it with while getline(finalFormat, fileLine) for a while now but just haven't had the time, but thank you for pointing it out :) – JavaNewb Sep 20 '16 at 02:41

1 Answers1

0

For such a task, I would do it the simple way. As we already know the number of lines and we know the pattern, I would simply keep a vector of strings (one entry per line of the final file) that I would update as I'm parsing the input file. Once it's done, I would iterate through my strings to print them into the final file. Here is a code that's doing it :

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

int main(int argc, char * argv[])
{
  int n = 6; // n = 3 * nAtoms

  std::ifstream in("test.txt");
  std::ofstream out("test_out.txt");

  std::vector<std::string> lines(n + 1);
  std::string line("");
  int cnt = 0;

  // Reading the input file
  while(getline(in, line))
  {
    lines[cnt] = lines[cnt] + " " + line;
    cnt = (cnt + 1) % (n + 1);
  }

  // Writing the output file
  for(unsigned int i = 0; i < lines.size(); i ++)
  {
    out << lines[i] << std::endl;
  }

  in.close();
  out.close();

  return 0;
}

Note that, depending of the structure of your input/ouput files, you might want to adjust the line lines[cnt] = lines[cnt] + " " + line in order to separate the columns with the right delimiter.

Thomas W.
  • 460
  • 3
  • 9