-1

I want to write a program that reads a file and calculates the sum of all integers in the file. In this file, each line has only string or integers, it cannot have both of them.

I wrote the program to read each character of each line, and if it's an ASCII code between 48-57 then use the extraction >> operator to save it, and do it again until EOF.

But, my issue is, when I read the first character of a line, if its a number then I lose the first digit of that number.

What can I do? I also tried using seekg(), but it couldn't help me.

//A program that read file and calculate sum of numbers in file 
#include <iostream>
#include <fstream>
#include <string.h>
int main ()
{

    // decalre File path string to store path of file
    std::string FilePath;
    //recive from a user 
    std::cin>>FilePath;
    //FilePath = "\""+ FilePath + "\"";
    //mine guide
    std::cout<<FilePath;

    //declare Infile object of input stream for only read file
    std::ifstream InFile ;
    //open file
    InFile.open(FilePath.c_str() , std::ios::in);
    //inser if condition if file does not opened
    if(!InFile)
    {
        std::cerr<<"can not open file ";
        return 1;
    }
    //what the hell is that  i forgot 
    std::string FileString ;
    //decalre char type check char to check the line start with number or charater
    char checkChar {};
    //declare NUminFilie to read Nums in file
    int  NumInFile{};
    // declare for calcualte sum of Nums in File
    int SumOfNumInFile{};
    //declare In vain string to go to next line in file
    std::string InVainString ;
    int counter = 0;
    std::cout<<"befot while\n";
    // insert a boolian variable falg  to avoid back cursor if number is in begening of file because 
    bool flagNotAtFirstOfFile = false;
    while (InFile.get(checkChar))
    {
    
    
    
        std::cout<<"get\n";
        std::cout<<(int)checkChar<<std::endl;
        if((((int)checkChar>=49)&&((int)checkChar<=57)))
        {
            std::cout<<"if char is done";
            if(flagNotAtFirstOfFile)
            {   std::cout<<"   seekg is done  "<<std::endl;
                InFile.seekg(,std::ios::cur);

            }
            else 
            {
                InFile.seekg(0,std::ios::beg);
                flagNotAtFirstOfFile = true;

            }
            InFile>>NumInFile;
            std::cout<<NumInFile<<std::endl;
            SumOfNumInFile+= NumInFile;



        }
        // insert if condition to if checkChar read space character between 2 line number continue and do not read line 
        else if ((int)checkChar ==10)
        {
            continue ;
        }
        else
        {
            InFile.seekg(0,std::ios::cur);
            std::getline(InFile,InVainString);
            std::cout<<"getline :"<<InVainString<<std::endl;
        }

        //std::cout<<"getline :"<<InVainString<<std::endl;
        //InFile.peek();
        

    }
    std::cout<<SumOfNumInFile;
    return 0;

}

The input file is like this:

232300
675
khobi
chekhabar
233
34340
hjhkjh
6757
876876
hehehhe
1100
end
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • 2
    FYI, you can remove the C language tag. The C language doesn't have `std::cout`. You should really not mix C and C++ languages unless you really need to. – Thomas Matthews Mar 17 '23 at 20:26
  • What's the deal with the magic numbers 49 and 57? Have you tried `std::isdigit()`? Or have you tried `'0'` and `'9'`? – Thomas Matthews Mar 17 '23 at 20:28
  • thanks for your attention yes i used '0' ,'9' but was a same result , it can reads first char and determine its integer but when if condition is true use extraction >> to save number but i lose first digit ,, i also use InFile.seekg(-1,std::ios::cur) but also can not read whole number – Mohammad Erfan Noori Mar 17 '23 at 20:30
  • You have my permission to add spaces around operators to improve readability, e.g. `" && " and ` << `. The effect of spaces in your code for build time is negligible, but the readability improvement is tremendous. – Thomas Matthews Mar 17 '23 at 20:31
  • 4
    Read a whole line using `std::getline`. Figure out if the string you've read is a number or not. If it is then convert the string to a number using `std::stoi` and process it. – Retired Ninja Mar 17 '23 at 20:36
  • please supply, a complete program, the input file – pm100 Mar 17 '23 at 20:39
  • file input is like this under each other : 45456465' 6786 gfvhgfjh kjhj 8687876 jhhkh – Mohammad Erfan Noori Mar 17 '23 at 20:46
  • please paste the actual text of the input file into the question, along with a comlete program – pm100 Mar 17 '23 at 20:51
  • i do not know how but i think i did it – Mohammad Erfan Noori Mar 17 '23 at 21:04

2 Answers2

2

Instead of actually reading each character with istream::get(), you could use istream::peek() first, and then make decisions about how to extract the next value from the stream based on the character's value, eg:

char checkChar;
int NumInFile;

while (InFile >> std::ws && InFile.peek(checkChar))
{
    if (isdigit(static_cast<unsigned char>(checkChar)))
    {
        InFile >> NumInFile;
        ...
    }
    else
        InFile.ignore(std::numeric_limits<streamsize>::max(), '\n');
}        

Otherwise, you can use istream::putback() to put a read character back into the stream so the next extraction will see it, eg:

char checkChar;
int NumInFile;

while (InFile >> std::ws && InFile.get(checkChar))
{
    if (isdigit(static_cast<unsigned char>(checkChar)))
    {
        InFile.putback(checkChar);
        InFile >> NumInFile;
        ...
    }
    else
        InFile.ignore(std::numeric_limits<streamsize>::max(), '\n');
}        

Otherwise, you could simply read each line in full into a std::string using std::getline(), and then you can use std::istringstream or std::stoi() or whatever you want to extract integers from the line as needed, eg:

std::string line;
int NumInFile;

while (std::getline(InFile, line))
{
    if (isdigit(static_cast<unsigned char>(line[0])))
    {
        NumInFile = std::stoi(line);
        ...
    }
}        
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
0

Pseudo code answer:

while get line from file (std::getline)
  inspect the first character for digit (std::isdigit)
  if digit
    convert string to number (std::stoi)
    add number to sum
  end
end
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
pm100
  • 48,078
  • 23
  • 82
  • 145
  • Your EOF check will likely lead readers to use `InFile.eof()` as the loop condition, which [should be avoided](https://stackoverflow.com/questions/5605125/). I would suggest rewriting that as `while read line into string (std::getline)` instead. The read will fail when EOF is reached, breaking the loop – Remy Lebeau Mar 23 '23 at 14:26