#include <string>
#include <fstream>
#include <cstdlib>
// To understand the solution, we need to understand the problem. If the i-th
// line in the file has i characters, it is perfect. For example, if the tenth
// line in the file contains ten characters, then it is perfect. If the first
// character in a line is the i-th character in the file and the line contains
// i characters, then the line is semi-perfect. For example, if the first
// character in a line is the twenty-seventh charcter in the file and the line
// contains 27 characters, then the line is semi-perfect. We want a program
// that finds perfect and semi-perfect lines in a file.
// To find perfect lines, the program needs to know the number of the current
// line in the file and the number of characters in the current line; that is,
// it needs to keep count of the number of lines in the file, and the number of
// characters in the current line. A line is perfect when those two values are
// equal. In other words, a line is perfect when line_pos = line_size, where
// line_pos is the number of the current line in the file and line_size is
// the number of characers in the current line.
// To find semi-pefrect lines, the program needs to know the position within
// the file of the first character of a line and the number of characters in
// the line; that is, it needs to keep count of the number of characters in the
// file and the line size. A line is semi-perfect when those two values are
// equal. In other words, a line is semi-prefect when char_pos = line_size,
// where char_pos is the file position of the line's first character line_size
// is the number of characters in the line.
// Almost all the necessary information needed to solve the problem is found by
// the algorithm created in the third design test. The one slight sticking
// point making sure that char_pos doesn't get changed while computing
// line_size; otherwise char_pos won't have the position of the first character
// in the line. The minimum and maximum line sizes and character count aren't
// needed for this problem, and can be dropped from the code.
int main() {
const string fname = "my.dat";
ifstream ins(fname.c_str());
if (!ins) {
cerr << "Can't open " << fname << ".\n";
return EXIT_FAILURE;
}
// Remember - line and character positions are numbered starting from 1.
int char_pos = 1;
int line_cnt = 1;
while (true) {
int line_size = 0;
int c;
// Find the number of characters in the current line. Set line_size to -1
// if there are no more lines in the file; otherwise set line_size to the
// number of characters in the line.
do {
c = ins.get();
if (c == EOF)
line_size = -1;
else
line_size++;
}
while ((line_size > -1) && (c != '\n'));
// If there are no more lines, there's nothing else to do.
if (line_size < 0) break;
// char_pos contains the file position of the first character in the
// current line, line_cnt contains the current line's number, and line_size
// contains the number of characters in the current line. With these
// values the tests for perfect and semi-prefect lines are simple. It is
// important that the tests for perfect and semi-perfect lines be kept
// separate because it is possible for a line to be both perfect and
// semi-perfect (how?).
if (line_cnt == line_size)
cout << "Line " << line_cnt << " is perfect.\n";
if (char_pos == line_size)
cout << "Line " << line_cnt << " is semi-perfect.\n";
// Update the file position variables for the next line.
char_pos += line_size;
line_cnt++;
}
ins.close();
}
syntax highlighted by Code2HTML, v. 0.9