0

I'm writing a program that can format text files of thousands of lines of data. The input text file are lines such as:

2010-01-01 00:00:00 0.520368 0.558565 0.567376

What I want to do is replace the dashes and ':' with spaces, and then put proper tabs in. I figured out how to fix the tab problem, but my algorithm for replacement just does not work. Any help is greatly appreciated. My code currently looks like this:

void getReportInfo(ifstream& file, ofstream& ofile)
{
  string date, time;
  double wheight1, wheight2, wheight3;


         while(!file.eof())
         {
           file >> date >> time >> wheight1 >> wheight2 >> wheight3;

           //replace dashes 
           for(int i = 0; i < date.length(); i++) {
             if(date[i]== '-')
               date[i] == ' ';
           }
           ofile << date << " ";

           //replace colons
           for(int i = 0; i < time.length(); i++) {
             if(time[i]== ':')
               time[i] == ' ';
           }
           ofile << time << " ";

           ofile << "\t" << wheight1 << " \t" << wheight2 << " \t" << wheight3 << endl;
         }
}
  • 1
    Fix this first: [`while(!file.eof())`](http://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong). After that neither `date[i] == ' ';` nor `time[i] == ' ';` are assigning anything. Those `==` should be `=`, and your compiler should warning you about both of them. If it doesn't, your warning level isn't high enough. – WhozCraig Feb 20 '15 at 18:59
  • I can't believe I did that. Thank you! My compiler never gives me warnings which is a problem. What's wrong with the eof though? I don't know what a better alternative would be to read files of unknown lengths. – scrambledeggs Feb 20 '15 at 19:06
  • @scrambledeggs read the linked question and answers I provided. It will explain it in detail. – WhozCraig Feb 20 '15 at 19:10
  • When this is **done**, do you want *no* spaces in your string *at all*, or do you want the spaces *initially* in the string to be replaced by tabs, then the `-` and `:` replaced with spaces? It makes a difference, and I hope it is clear why. – WhozCraig Feb 20 '15 at 19:17
  • @scrambledeggs _"What's wrong with the eof though?"_ Click that link, I've linked it in my answer also. – πάντα ῥεῖ Feb 20 '15 at 19:22

3 Answers3

2

First of all, while(!file.eof()) is considered wrong.

What I want to do is replace the dashes and ':' with spaces, and then put proper tabs in.

If you're really just after replacing '.' and '-' with ' ' You should have something like

 std::string line;
 while(std::getline(file,line)) {
      std::replace(std::begin(line),std::end(line),'-',' ');
      std::replace(std::begin(line),std::end(line),'.',' ');
      ofile << line << std::endl;
 }

I'm not really sure, what you consider proper tabs, but 1st reading to line, would serve you well still to parse the particular values you're interested in. You just parse the wanted values from the line using std::istringstream:

 std::istringstream iss(line);
 iss >> date >> time >> wheight1 >> wheight2 >> wheight3;
Community
  • 1
  • 1
πάντα ῥεῖ
  • 83,259
  • 13
  • 96
  • 175
  • There's no `string` member `replace` function that takes those arguments unfortunately. You need to use the standalone `replace` algorithm or use a combination of member `find` and member `replace`. – mattnewport Feb 20 '15 at 19:14
2

Use replace from the <algorithm> header:

replace(begin(date), end(date), '-', ' ');
replace(begin(time), end(time), ':', ' ');
mattnewport
  • 12,751
  • 2
  • 30
  • 38
1

C++11's get_time/put_time actually provides you with an even better solution:

tm foo;

while (!file.eof())
{
    file >> get_time(&foo, "%Y-%m-%d %H:%M:%S") >> wheight1 >> wheight2 >> wheight3;
    ofile << put_time(&foo, "%Y %m %d %H %M %S") << "\t" << wheight1 << " \t" << wheight2 << " \t" << wheight3 << endl;
}

Of course you know from other posts that you need to handle your loop condition better.

Another note is that gcc 4.9.2 does not support get_time/put_time.

And a final note, the best way to read this in would have been with get_time(&foo, "%F %T") however even Microsoft doesn't seem to support that :(

I know that you're probably thinking now that put_time/get_time are some sketchy backwater solution, but I assure you this is kosher C++11.

Jonathan Mee
  • 35,107
  • 16
  • 95
  • 241