0

I am working on a program to read floating point number from an txt file and store in array, and I need to check are there any invalid input like character. My code is:

int main() {
    string line;
    ifstream myfile("data.txt");
    int size;
    float* result;
    if (myfile.is_open()) {
        getline(myfile, line);
        size = stoi(line);
        result = new float[size];
        for (int i = 0; i < size; i++) {
            myfile >> result[i];
            /*if ( (isdigit(arr[i])==0) ){
                    cout << "Invaild input." << endl;
                    return 0;
            }*/
        }
        myfile.close();
    }
    else {
        return 0;
    }
}

The first line of the txt file is the size of the array and the second line is the contents like

5 //size
1 -2 9.2 4.7 -5.2  //content

How can I check that is there any character exist in the array like 1 -2 B 4.7 -5.2 //Invalid input ? I try the isdigit function but it fail.

kali
  • 117
  • 7
  • Did you mistyped `n` instead of `size`? Please note that you can always [check](https://stackoverflow.com/questions/61623803/why-can-stdcin-not-be-implicitly-converted-to-bool) `myfile` after any extraction. – Bob__ Oct 19 '21 at 08:30
  • Also, you can use [`std::stof`](https://en.cppreference.com/w/cpp/string/basic_string/stof), checking all the paremeters. – Bob__ Oct 19 '21 at 08:40
  • @kali i have given 2 ways to solve this problem. Check them out. One is using `std::vector` which is the recommended way and can be found [here](https://www.onlinegdb.com/GeYzWFO9kd) and other method is to use built in array and can be found [here](https://www.onlinegdb.com/BVJTPCCsZ) . – Jason Oct 19 '21 at 09:47
  • If you want to check each token (word between space) into the line, you can try three of these options: 1. for each token, use a regex expression to validate the input, something like `[-.\d]+`. 2. Convert each token to a number (string to double) and wait for whether it returns a valid digit or not. 3. If you want to find any character not allowed into the line, use a regex to find any character wich could produce an error: `[^\d.-\s]` – Jorge Omar Medra Oct 19 '21 at 14:28

2 Answers2

0

If you get an invalid input, reading will fail, and you can check this in the usual manner.

if (myfile >> result[i])
{
    // Handle success.
}
else
{
    // Handle failure.
}
molbdnilo
  • 64,751
  • 3
  • 43
  • 82
  • But how can I determine the input is invalid or not? – kali Oct 19 '21 at 08:58
  • If you end up in the `else` branch, the input was not a valid float. (Read some more about stream I/O in your favourite C++ book.) – molbdnilo Oct 19 '21 at 09:04
  • @kali i have given 2 ways to solve this problem. Check them out. One is using `std::vector` which is the recommended way and can be found [here](https://www.onlinegdb.com/GeYzWFO9kd) and other method is to use built in array and can be found [here](https://www.onlinegdb.com/BVJTPCCsZ) . – Jason Oct 19 '21 at 09:53
-1

I have given 2 solutions. One uses built in arrays and other uses std::vector.

Solution 1: Using built in array

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
int main()
{
    
    std::string line;

    std::ifstream inFile("input.txt");
   
   //in case of using array, size must be fixed and predetermined 
   double arr[120] = {0.0}; //you can choose size according to your needs
    if(inFile)
    {
        double i = 0;//this variable will be used to add element into the array
        int count = 0;
        while(getline(inFile, line, '\n'))        
        {
            
            
            
            std::istringstream s(line);
            
            //take input(from s to i) and then checks stream's eof flag status
            while(s >> i || !s.eof()) {
                //check if either failbit or badbit is set
                if(s.fail()) 
                {
                    //clear the error state to allow further operations on s
                    s.clear();
                    std::string temp;
                    s >> temp;
                    continue;
                 }
                else 
                {
                    
                    arr[count] = i;
                    ++count;
                    
                    //break out of the loop so we do go out of bounds 
                    if(count >=120)//note 120 is the size of the array and you can change it according to your needs
                    {
                        break;
                    }
                }

}
            
            
        }
    }
    else 
    {
        std::cout<<"file could not be read"<<std::endl;
    }
    inFile.close();
    
    for(double i: arr)
    {
        std::cout<<"elem: "<<i<<std::endl;
    }
   
    return 0;
}              

The output of solution 1 can be seen here.

Solution 2: Using std::vector

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
int main()
{
    
    std::string line;;

    std::ifstream inFile("input.txt");
    
   std::vector<double> vec;
    if(inFile)
    {
        double i = 0;//this variable will be used to add element into the vector
        
        while(getline(inFile, line, '\n'))        
        {
            
           
            
            std::istringstream s(line);
           //take input(from s to i) and then checks stream's eof flag status
            while(s >> i || !s.eof()) {
                if(s.fail()) 
                {
                    //clear the error state to allow further operations on s
                    s.clear();
                    std::string temp;
                    s >> temp;
                    continue;
                 }
                else 
                {
                    vec.push_back(i);
                }

            }
            
            
        }
    }
    else 
    {
        std::cout<<"file could not be read"<<std::endl;
    }
    inFile.close();
    
    for(double i: vec)
    {
        std::cout<<"elem: "<<i<<std::endl;
    }
   
    return 0;
}

The ouput of solution 2 can be seen here.

Important Note

The advantage of using std::vector over built in array(in this case) is that you don't have know the size of the vector beforehand. So it is preferable because you don't know how many integers are there in the input.txt file. std::vector can handle this correctly(dynamically). But when using built in arrays you must know/specify the size of the array beforehand. This in turn means you must know beforehand how many integers are there in the input.txt, which is not practical.

Jason
  • 36,170
  • 5
  • 26
  • 60
  • you dont check if input is valid. – 463035818_is_not_an_ai Oct 19 '21 at 09:10
  • Yes i missed it. I am going to correct it and edit my answer. – Jason Oct 19 '21 at 09:12
  • @463035818_is_not_a_number I have edited my answer to give correct desired output. Check it out. `std::vector` version can be found [here](https://onlinegdb.com/Owh7d4Yb6) . – Jason Oct 19 '21 at 09:26
  • Code without explanation is not a good answer. Stack Overflow is not a service for giving homework solutions to students. It is supposed to provide information. The reader should be informed about how the code accomplishes the goal and what the parts are supposed to do. – Eric Postpischil Oct 19 '21 at 11:06