hello

i decide to first learn about file streams before learning oop concepts in c++.
want to read single digit from the textfile. actually text file contains numbers from 0 to 9. And these are 9 in a row and 3 row are there. you can think of its content as following :

123456789
012345678
010234567

what i need is that how to read first three digits from each row.Here i'm confused with what data type should i opt. i thought int would be good but later realised that int would read entire line as a number. Now i think that char would be better. further it can be converted to integer using type casting.

the second point is that how read first three digits.for that i use this :

for(i=0;i<3;i++)
    {
        readob>>a[i];
        total+=(int)a[i];
    }

is that correct ?

And the last point is that after reading three digits , how to set readob to newline.

Edited 2 Years Ago by Learner010

I would read in the entire line and then break it up.

string line;
int total = 0;

ifstream fin("file.txt");

while (getline(fin, line))  // get the line
{
    // loop by three
    for (size_t i = 0; i < line.size() i += 3)
        total += atoi(line.substr(i, 3).c_str()); // get the substring and convert to int
}

thanx for your quick reply.
i try the code but it doesn't seem to be working. here is the code

#include<iostream>
#include<fstream>
#include<string>
#include<stdlib.h>
using namespace std;
int main()
{
    ifstream readob;
    string line;
    long int total=0;
    readob.open("file.txt");
    while(getline(readob,line))
    {
        for (size_t i = 0; i < line.size();i+=3)
        total += atoi(line.substr(i, 3).c_str());
    }
    cout<<total;
    return 0;
}

what is missing there ?it prints zero(0) but it should print 10(1+2+3+0+1+2+0+1+0)
one more question : what does it mean by size_t?

it should print 10(1+2+3+0+1+2+0+1+0)

So, you want to add together the first three digits of each row. Right? I say that because NathanOliver's code assumes that you want to interpret the first three digits as one number, and add the three (for each row) together, i.e., it should print 145 (123+12+10).

Your code:

for(i=0;i<3;i++)
{
    readob>>a[i];
    total+=(int)a[i];
}

is not correct, but almost. First of all, you don't need a cast to int, because char is already an integral type. Second, you don't actually need an array of chars, because you use it only temporarily inside the loop. And last but not least, the character (digit) that you read from the stream is a string character, i.e., a byte value that ends up translating into a printable digit (see the ascii table of one example of the encoding used). In other words, a char that is printed as "2" will actually have a numerical value (when treated as an integer) of 50 (if ascii is used, but it could be something else). So, your additions of 1+2+3 is not going to give 6, but probably 150 (49+50+51). To convert a char digit into an integer number, you can just do c - '0' because the digits are always (I think) in order in the encodings (ascii, UTF8, etc.). So, with those things in mind, your code should be:

for(int i = 0; i < 3; ++i)
{
    char c;
    readob >> c;
    total += c - '0';
}

That will, of course, only take care of the first three digits of the first line. If you want to ignore the other characters until you get to the next line, then you can use the ignore function, like this:

readob.ignore(256, '\n');

which will ignore all characters (well, less than 256 characters) until you see a "new-line" character '\n'.

If you place all that in a loop, you get the complete program:

#include<iostream>
#include<fstream>

using namespace std;

int main()
{
    ifstream readob;
    int total = 0;
    readob.open("file.txt");

    for(int j = 0; j < 3; ++j)
    {
        for(int i = 0; i < 3; ++i)
        {
            char c;
            readob >> c;
            total += c - '0';
        }
        readob.ignore(256, '\n');
    }

    cout << total;
    return 0;
}
Comments
very helpful

a lot thanks for very very nice explanation.

but one point is still unclear for me.

To convert a char digit into an integer number, you can just do c - '0'

earlier you said that char is already an integral type therefore there should be implicit type casting (which result in integer because integer is higher than char , correct ?. So , for number 2 there is ascii representation 50 and 50-'0'=50. but infact it does what i want(i.e it is considered as 2 instead of 50 ).

so would you make it(c-'0') more clear for me ?
sorry , if my question is silly.

Edited 2 Years Ago by Learner010

A char is an intergal type. That does not mean that a char is an int but it is of a type that will be implicitly converted to an int. 50-'0'=50 is not correct. What it is saying is take 50 and subtract the value of that char '0'. In ascii '0' = 48 so it becomes 50 - 48 = 2. The reson we right it as total += c - '0' is because if you are on a system that uses a charecter code other than ascii this will still work. the character '0' will always come before '1' in the code set so '1' - '0' = 1 (integer).

the character '0' will always come before '1' in the code set so '1' - '0' = 1 (integer).

you mean their internal representation is in adjacent format.therefore no matter what character coding we are using because every character encoding sets alphabets in a sequence. correct ?

50-'0'=50 is not correct.

I realized it now. I think this is because 50(integral representation of 2) is ascii value ,equivalent to 2 and '0' is character and its integral representation is 48. that's why it remain 2(50-48). correct ?

I would like to thanks everyone who participate in this thread(special thanks goes to mike and then NathanOliver for clearing the concepts with their deep knowledge).

Sorry for continuing this thread with one more doubt:

How to read last 3 characters in a line(i want to read digits recursively in a line) ?.I have no clue about how to set the file cursor to the end of the line and then start reading.

Once again the BIG thanks for giving your valuable time to this thread.

you mean their internal representation is in adjacent format.therefore no matter what character coding we are using because every character encoding sets alphabets in a sequence. correct ?

Correct. I'm not sure if it is absolutely guaranteed, but all encodings that I have ever heard of has this property (letters in alphabetical order and digits in order 0-9). Someone would have to be pretty insane to come up or use an encoding that does not have this property, because many functions rely on this, like doing string to number conversions (and vice versa), and things like turning all characters into upper-case or lower-case. So, if an encoding existed which did not have this property, most of that code would be broken (not working properly).

How to read last 3 characters in a line(i want to read digits recursively in a line) ?.I have no clue about how to set the file cursor to the end of the line and then start reading.

For that kind of task, it's preferrable to just read the entire line into a string and then deal with the characters in the string. C++ strings (the std::string class) are just arrays of characters with many more features for string manipulation, like extracting a sub-string (part of the string), finding specific characters, etc... You can read an entire line with the std::getline function (see ref), like this:

std::string line;
std::getline(readob, line);
std::string last_three = line.substr( line.size() - 3 );

which reads a line into the string line and then, creates a sub-string with the last three characters only.

IO-streams also have some capabilities for reading ahead and fetching specific characters (peek, seekg, tellg, etc..), but it's a hassle to use, and it is rather inefficient. IO-streams are optimized and intended for sequential use (i.e., no going back and forth).

For that kind of task, it's preferrable to just read the entire line into a string and then deal with the characters in the string. C++ strings (the std::string class) are just arrays of characters

Yes , the string is array of characters. I declare line variable of type string.

You can read an entire line with the std::getline function

Yes , I did it like this

while(getline(readob,line))
{


}

I think that getline(readob,line) inside while ,will be evaluated as true until EOF , Correct ?

Working Code based on the suggestions

#include<iostream>
#include<fstream>
using namespace std;
int main()
{
    ifstream readob;
    int total = 0,i;
    string line;
    readob.open("file.txt");
    while(getline(readob,line))
    {
        i=line.size()-3;
        for(; i < line.size(); i++)
        {
            char c;
            c=line[i];
            total += c - '0';
        }
    }
    cout << total;
    return 0;
}

Confusion about NULL

There are 9 characters(digits) in a row in a file and its(line) size is 9(I checked it with cout<<line.sizeof(); ). I read somewhere that string is one extra character(that is NUll).And therefore its size should be 10 instead of 9. I don't understand this concept.Would you guys this clear this concept ?

Suggestion to Newbie

write a program in c++ to input two numbers and display

Don't Hijack other's thread. Feel free to create your own thread. And don't ask to write program here , because nobody will do this for you.We provide assistance in case when you prove that you did a lot but couldn't do that.As an evidence you can post your code here with code button

Learner010: The string objects size is only going to give you the number of alphanumeric characters in the string. It is not going to count the null at the end since it handles it for you. In the following block of code why are you subtracting 3 from the size of the line?

while(getline(readob,line))
{
    i=line.size()-3;
    for(; i < line.size(); i++)
    {
        char c;
        c=line[i];
        total += c - '0';
    }
}

If you are trying to get the last three digits from each line you need to do this

while(getline(readob,line))
{
    // set temp to a substring of line starting from  3 back from the end
    for(int i = 0, string temp = line.substring(line.size() - 3); i < 3); i++)
    {
        char c;
        c = temp[i];
        total += c - '0';
    }
}

why are you subtracting 3 from the size of the line?

I did so to get the last third position in the string line.

Here is little modification to your code

while(getline(readob,line))
{
    // set temp to a substring of line starting from  3 back from the end

    for(i = 0, temp = line.substr(line.size()-3); i < 3; i++)
    {
        char c;
        c = temp[i];
        total += c - '0';
    }
}

i don't think to opt this code because it has extra variable and extra library function(i heard that it isn't good practice). Correct ?

i want to know more about NULL ?

i am confused by different outputs(i know this is because of NULL)

char stri[]="hello";
cout<<sizeof(stri);

this prints 6
this one

string stri="hello";
cout<<stri.size();

and this prints 5

it appears to me that string variable doesn't terminated with NULL where as actual array of characters does.

There is nothing wrond with using the function provided by the STL. You are using string so you might as well use what string offers.

char stri[]="hello";
cout<<sizeof(stri);

In the above code you get six becasue if you look at stri in memory it looks like this 'h', 'e', 'l', 'l', 'o', '\0' where '\0' is how null is represented as a string character. Now the array that the string objects holds onto may or may not be the same but since it is a class it can have a member variable that keeps track of the size. With c style strings aka char stri[]="hello"; you need the null at the end to mark where the string ends when passing it to functions. Otherwise you would need to always keep track of the size of the array and pass it to functions like you do when dealing with arrays of numbers.

As a side note when you write char stri[]="hello"; it is exactly the same as writing char stri[] = {'h', 'e', 'l', 'l', 'o', '\0'};.

This article has been dead for over six months. Start a new discussion instead.