Converting Between Tabs and Spaces in a Text File

Problem

You have a text file that contains tabs or spaces, and you want to convert from one to the other. For example, you may want to replace all tabs with three spaces, or you may want to do just the opposite and replace occurrences of some number of spaces with a single tab.

Solution

Regardless of whether you are replacing tabs with spaces or spaces with tabs, use the ifstream and ofstream classes in . In the first (simpler) case, read data in with an input stream, one character at a time, examine it, and if it's a tab, write some number of spaces to the output stream. Example 4-23 demonstrates how to do this.

Example 4-23. Replacing tabs with spaces

#include 
#include 
#include 

using namespace std;

int main(int argc, char** argv) {

 if (argc < 3)
 return(EXIT_FAILURE);

 ifstream in(argv[1]);
 ofstream out(argv[2]);

 if (!in || !out)
 return(EXIT_FAILURE);

 char c;
 while (in.get(c)) {
 if (c == '	')
 out << " "; // 3 spaces
 else
 out << c;
 }
 
 out.close( );

 if (out)
 return(EXIT_SUCCESS);
 else
 return(EXIT_FAILURE);
}

If, instead, you need to replace spaces with tabs, see Example 4-24. It contains the function spacesToTabs that reads from an input stream, one character at a time, looking for three consecutive spaces. When it finds three in a row, it writes a tab to the output stream. For all other characters, or for fewer than three spaces, whatever is read from the input stream is written to the output stream.

Example 4-24. Replacing spaces with tabs

#include 
#include 
#include 
#include 
#include 

using namespace std;

void spacesToTabs(istream& in, ostream& out, int spaceLimit) {

 int consecSpaces = 0;
 char c;

 while (in.get(c)) {
 if (c != ' ') {
 if (consecSpaces > 0) {
 for (int i = 0; i < consecSpaces; i++) {
 out.put(' ');
 }
 consecSpaces = 0;
 }
 out.put(c);
 } else {
 if (++consecSpaces == spaceLimit) {
 out.put('	');
 consecSpaces = 0;
 }
 }
 }
}

int main(int argc, char** argv) {

 if (argc < 3)
 return(EXIT_FAILURE);

 ifstream in(argv[1]);
 ofstream out(argv[2]);

 if (!in || !out)
 return(EXIT_FAILURE);

 spacesToTabs(in, out, 3);

 out.close( );

 if (out)
 return(EXIT_SUCCESS);
 else
 return(EXIT_FAILURE);
}

 

Discussion

The mechanism for both of these solutions is the same; only the algorithms differ. Read characters from an input stream using get, and put them to an output stream with put. Put your logic for doing the translation between calls to these two functions.

You probably noticed in Example 4-24 that in main I declared in and out to be of types ifstream and ofstream, respectively, and that the parameters to spacesToTabs are actually istream and ostream. I did this to allow spacesToTabs to work on any kind of input or output streams (well, not any kind of streamones that inherit from basic_istream or basic_ostream), and not just file streams. For example, you may have the text you want to reformat in a string stream (istringstream and ostringstream in ). In that case, do something like this:

istringstream istr;
ostringstream ostr;

// fill up istr with text...

spacesToTabs(istr, ostr);

As with strings, streams are actually class templates that are parameterized on the type of character the stream operates on. For example, an ifstream is a typedef for basic_ifstream, and a wifstream is a typedef for basic_ifstream. Thus, if you need spacesToTabs from Examples Example 4-23 or Example 4-24 to work on a stream of any kind of character, you can use the class templates instead of the typedefs:

template
void spacesToTabs(std::basic_istream& 




in,
 std::basic_ostream& out,
 int spaceLimit) { //...


Building C++ Applications

Code Organization

Numbers

Strings and Text

Dates and Times

Managing Data with Containers

Algorithms

Classes

Exceptions and Safety

Streams and Files

Science and Mathematics

Multithreading

Internationalization

XML

Miscellaneous

Index



C++ Cookbook
Secure Programming Cookbook for C and C++: Recipes for Cryptography, Authentication, Input Validation & More
ISBN: 0596003943
EAN: 2147483647
Year: 2006
Pages: 241

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net