2

I have an input text file of 4 lines, each line is 80 characters fixed length. I want to replace every comma by a space. I have written code shown as follows and compiled and run in Code::Blocks IDE. The problem is that the output file contains an extra line.Kindly help me correct the mistake. I'm a beginner in C++.

inputFile

outputFile

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


using namespace std;

int main()
{
ifstream in("circArc.txt", ios::in | ios::binary);


if(!in)
{
    cout << "Cannot open file";
    return 1;
}

ofstream out("readInt.txt", ios::out | ios::binary);
if(!out)
{
    cout << "Cannot open file";
    return 1;
}

string str;
char rep[80]; //replace array

while(in)
{
    getline(in,str);
    for(int i=0; i<80; i++)
    {
        if(str[i] == ',')
            rep[i] = ' ';
        else
            rep[i] = str[i];
        out.put(rep[i]);
    }
    out << endl;

}
in.close();
out.close();
return 0;
}
Vishal
  • 35
  • 1
  • 1
  • 5

5 Answers5

3

One way to replace a character in a file using C++.

#include <iostream>
#include <fstream>
int main()
{
    std::fstream fs("testFile.txt", std::fstream::in | std::fstream::out);
    if (fs.is_open()) {
        while (!fs.eof()) {
            if (fs.get() == ',') {
                fs.seekp((fs.tellp() - static_cast<std::streampos>(1)));
                fs.put(' ');
                fs.seekp(fs.tellp());
            }
        }
        fs.close();
    } else {
        std::cout << "Faild to open" << '\n';
    }
    return 0;
}
CMHAS
  • 31
  • 5
2

The problem with using

while(in)
{
    getline(in,str);

is that you are not checking whether getline succeeded. You are proceeding to use str regardless.

Replace

while(in)
{
    getline(in,str);
    ...
}

with

while(getline(in,str))
{
    ...
}
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • @Antony, Take a look at the answer to this SO question. http://stackoverflow.com/questions/42571529/how-to-count-the-number-of-lines-in-a-file-using-c. It appears as though you have run into the same situation. – R Sahu Mar 03 '17 at 08:21
  • @Antony : Because you are calling getline() twice – androidFan Mar 03 '17 at 08:22
0

Keep the while() loop, but do it once before/outside the while loop and then inside the while loop in the last line :

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


using namespace std;

int main()
{
ifstream in("circArc.txt", ios::in | ios::binary);


if(!in)
{
    cout << "Cannot open file";
    return 1;
}

ofstream out("readInt.txt", ios::out | ios::binary);
if(!out)
{
    cout << "Cannot open file";
    return 1;
}

string str;
char rep[80]; //replace array

getline(in,str);

while(in)
{
    for(int i=0; i<80; i++)
    {
        if(str[i] == ',')
            rep[i] = ' ';
        else
            rep[i] = str[i];
        out.put(rep[i]);
    }
    out << endl;

    getline(in,str);

}

in.close();
out.close();
return 0;
}
androidFan
  • 611
  • 2
  • 19
  • 31
0

I think the problem here is the exit condition in your while loop. You can use:

 while(getline(in, str)) {
     if (in.eof()) {
         break;
     } 
     /** This will get you out if you are reading past the end of file
     * which seems to be the problem.
     */
     ...
C. Miranda
  • 75
  • 1
  • 6
0

The problem is that std::getline removes the end-of-line character if it exists so you can't (easily) tell if the final character was an end-of-line or not.

It seems to me you don't need to wory about the format of your data for this task so you could just process it one character at a time:

ifstream in("circArc.txt", ios::in | ios::binary);

ofstream out("readInt.txt", ios::out | ios::binary);

for(char c; in.get(c); out.put(c))
    if(c == ',')
        c = ' ';

If you really want to process line by line then you need to check if the line read in contained an end-of-line character and only include an end-of-line in the output if there was one in the input:

ifstream in("circArc.txt", ios::in | ios::binary);

ofstream out("readInt.txt", ios::out | ios::binary);

for(std::string line, eol; std::getline(in, line); out << line << eol)
{
    // only add an eol to output if there was an eol in the input
    eol = in.eof() ? "":"\n";

    // replace ',' with ' '
    std::transform(std::begin(line), std::end(line), std::begin(line),
        [](char c){ if(c == ',') return ' '; return c; });
}
Galik
  • 47,303
  • 4
  • 80
  • 117