Question 2. File I/O [6]

Suppose we are working with text files containing student numbers, where the acceptable file format is exactly one student number per line, where each student number is 9 digits long.

 E.g. 3 files with valid content

123456789
111222333 345600011 123450000
000000000 999999999 111111111
 E.g. 4 files with invalid content

12xyz6789
111222333 111111111 222222222 123450000
1234
1122334455

Write a function that takes a filename as a parameter (string or character array, your choice) and checks whether or not the file conforms to the format specified. (I.e. open the file, read it, determine if it matches the specifications, and close it.) The function should return true if the file is readable and appropriately formatted, false otherwise. The function should not produce any output, and should not modify the file contents in any way.
SAMPLE SOLUTION 1
bool checkFile(char fname[])
{
   // try to open the file
   ifstream fpin;
   fpin.open(fname);
   if (fpin.fail()) return false;

   // read lines one at a time until end of file
   while (!fpin.eof()) {
      // try reading the start of the next line of the file
      char c;
      fpin.get(c);

      // if we are at the end of the file then we
      //    did not encounter any invalid content
      if (fpin.eof()) {
         fpin.close();
         return true;
      }

      // otherwise we should get 9 digits with no errors
      int digitCount = 0;
      do {
         // make sure the line doesn't contain invalid characters
         if (isdigit(c)) digitCount++;
         else {
            fpin.close();
            return false; 
         }

         // get the next character
         fpin.get(c);

         // if we hit eof before 9 digits then this line is incomplete
         if ((digitCount < 9) && (fpin.eof()) {
            fpin.close();
            return false;
         }

      } while (digitCount < 9);

      // if we are at eof then the last line was complete,
      //    otherwise the current character should be the 
      //    newline marking the end of the line
      if (fpin.eof()) {
         fpin.close();
         return true;
      }
      if (c != '\n') {
         fpin.close();
         return false;
      }
   }
}
 SAMPLE SOLUTION 2
bool checkFile(string fname)
{
   // try to open the file
   ifstream fpin;
   fpin.open(fname.c_str());
   if (fpin.fail()) return false;

   // read lines one at a time until end of file
   while (!fpin.eof()) {
      string line;
      getline(fpin, line);
      if (!fpin.eof()) {
         // make sure the line has the right length
         if (line.length() != 9) {
            fpin.close();
            return false;
         }
         // make sure the contents are all digits
         for (int i = 0; i < 9; i++) {
             if (!isdigit(line[i])) {
                fpin.close();
                return false;
             }
         }
      }
   }

   // close and quit
   fpin.close();
   return true;
}

Other tests to make sure a char c contains only digits: // check char is within range '0' to '9' if ((c < '0') || (c > '9')) { // invalid char } // or check char matches one of '0' through '9' if ((c != '0') && (c != '1') && ... && (c != '9')) { // invalid char }
Other ways to read a line could be things like this: const int size = 11; // must be > 10 for this to work char text[size]; fpin.getline(text, size-1); if (strlen(text) != 9) { // line is too long or too short }