0

I'm writing a program which needs to read a text file and check first line of the text file for a number between 0 to 10. I have come up with a couple of solutions but there is still a problem:

How I read the file:

const string FileName= argv[1];
ifstream fin(argv[1]);
if(!fin.good()){
    cout<<"File does not exist ->> No File for reading";
    exit(1);
}
getline(fin,tmp);
if(fin.eof()){
    cout<<"file is empty"<<endl;
}
stringstream ss(tmp);

first I used atoi:

const int filenum = atoi(tmp.c_str());
    if(filenum<1 || filenum>10){
        cout<<"number of files is incorrect"<<endl;
        //exit(1);
    }

If the first line is a character, change it to zero But I want to call an exception and terminate the program.

Then I used isdigit but my entry is a string and it does not work with string. Finally I used each character in string but still does not work.

   stringstream ss(tmp);
   int i;
   ss>>i;
   if(isdigit(tmp[0])||isdigit(tmp[1])||tmp.length()<3)
   {}
Saksham
  • 9,037
  • 7
  • 45
  • 73
Bernard
  • 4,240
  • 18
  • 55
  • 88
  • Can you show how you are reading from the file ? And you have to use `&&` operation instead of `||` while doing the sanity check. Otherwise, you can test the state/flag of the stream after the extraction operation. – Mahesh Aug 13 '13 at 02:57
  • I have edited so you can see how I read the file – Bernard Aug 13 '13 at 03:01
  • Ok. For error checking you can just try - `if ( !(ss >> i) ) { std::cerr << "Invalid number."; }` – Mahesh Aug 13 '13 at 03:05
  • I already checked this. the problem is if the entry is 10D it only read 10 and ignore d at the end? – Bernard Aug 13 '13 at 03:16

2 Answers2

1

I would probably read the line with std::getline, then use a Boost lexical_cast to convert to int. It will throw an exception unless the entirety of the input string can be converted to the target type -- exactly what you want.

Of course, you'll also need to check that the converted result is in the correct range, and also throw the exception if it's out of range.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • I tried it but #include is not working in my header file and is not recognizable! any idea? – Bernard Aug 13 '13 at 03:13
  • @Bernard: Have you downloaded Boost and configured your compiler (and IDE, if you're using one) to find where you installed Boost? – Jerry Coffin Aug 13 '13 at 03:14
  • Oh the problem is I have to run my program on banshee server which I can't install anything! Is there any other solution? – Bernard Aug 13 '13 at 03:17
  • @Bernard: You only need to have the header available while you compile. Running it doesn't/won't require installing anything extra. – Jerry Coffin Aug 13 '13 at 03:38
1
#include <iostream>
#include <fstream>
#include <cstdio>
#include <cstdlib>
using namespace std;

bool isValidNumber (string str)
{
  if (str.length() > 2 || str.length() == 0)
    return false;
  else if (str.length() == 2 && str != "10")
    return false;
  else if (str.length() == 1 && (str[0] < '0' || str[0] > '9'))
    return false;
  return true;
}

int main()
{
  ifstream fin(argv[1]);
  if(!fin.good())
  {
    cout<<"File does not exist ->> No File for reading";
    exit(1);
  }

  //To check file is empty http://stackoverflow.com/a/2390938/1903116
  if(fin.peek() == std::ifstream::traits_type::eof())
  {
    cout<<"file is empty"<<endl;
    exit(1);
  }
  string tmp;
  getline(fin,tmp);
  if (isValidNumber(tmp) == false)
  {
    cerr << "Invalid number : " + tmp << endl;
  }
  else
  {
    cout << "Valid Number : " + tmp << endl;
  }
}
thefourtheye
  • 233,700
  • 52
  • 457
  • 497