Thread: Retrieving data from a file

  1. #31
    Registered User
    Join Date
    Feb 2010
    Posts
    31
    I am using my "fake" game as a way to learn programming. All the code I have posted here (as i have said numerous times now) its merely to help me learn what i am doing. Its completely junk and will never be used for anything.
    I have watched a total of 6 tutorials on youtube and this is what i wrote after learning those tutorials.
    I have asked a few questions on the forums to help me correct some confusions in my code. But thats it.

    I know NOTHING about programming. I am trying to learn. Im starting very basic.
    I dont know any ways to apply anything yet! thats what im trying to learn by asking my questions.

    I am reading a few C++ books, and i've been reading over all the documentation everyone has posted here for me. It's definitely a slow process but I'll get there.

    One of the articles here on cprogramming.com says to come up with an idea that you dont know how to do, then start writing code and not be afraid of not knowing what you are doing. So thats what i've done.

    I will try to read over Phantom's and Mk27s code and see if i can understand whats going on.
    I know there are MUCH better ways to write what little i have here, but as of now, Im learnin one thing at a time

    I appreciate everyone's helping me. Please understand how new i really am.

  2. #32
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by kamitsuna View Post
    I am using my "fake" game as a way to learn programming. All the code I have posted here (as i have said numerous times now) its merely to help me learn what i am doing. Its completely junk and will never be used for anything.
    That's totally fine, you are right to have a focus -- something you want to do -- while learning.

    I just meant that you have gotten a little carried away, because what you are doing is trying to take what you already know (cout, cin) and get as far as you can while pursuing "the goal".

    That's not what you need to do. You don't what to be relying on what you already know, when you know very, very little about C++. You want to be learning more!

    You have some C++ books, great. Here's an idea:

    1) deal with each new concept by writing as short a program as you can to use that concept (but don't just copy the code in the book).

    2) once that program works, try and think how this concept might be used in your bigger project.

    So, thinking about your original question, "Retrieving data from a file": what is the shortest program you could write that involves retrieving data from a file? Of course, you also want to take that data and put it into different variables, not just print it out. Here's an example. I made a text file like this:
    Code:
    kamitsuna  
    newbie
    666
    The first line will be your name, the second your role, the third is the number of the beast Now I'm gonna write a program that reads the file and prints out:

    You: kamitsuna
    Role: newbie
    # of the beast: 666


    using C++. I'll be back in a (few) minute(s)...
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  3. #33
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Okay I'm done!
    Code:
    #include <fstream>
    #include <string>
    using namespace std;
    
    // define the filename so it can be changed easily
    #define FILENAME "short.txt"
    
    int main() {
    	ifstream file(FILENAME);
    	string name, role;
    	int num_of_beast;
    
    	// check if file was opened properly
    	if (file.fail()) {
    		cout << "Could not open " 
    			<< FILENAME
    			<< "! Exiting..." 
    			<< endl;
    		return -1;
    	}
    
    	// if program is still running, the file is ready to read
    	getline(file, name);
    	getline(file, role);
    	num_of_beast = file.get();
    
    	file.close();
                   
    	// now print the data
    	cout << "You: " << name << endl
    		<< "Role: " << role << endl
    		<< "# of the beast: " << num_of_beast
    		<< endl;
    
    	return 0;
    }
    Here's the output:

    You: kamitsuna
    Role: newbie
    # of the beast: 54


    AHHHHH! Everything is okay except the number!!! WHY?????

    Actually I know why, and I can fix that, but first I have to go attend to some civic duties by shovelling snow.

    If you come back (kamitsuna) and have any questions about this, just ask.
    Last edited by MK27; 02-26-2010 at 02:29 PM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  4. #34
    Registered User
    Join Date
    Feb 2010
    Posts
    31
    HA! This is what i was looking for. I will mess with this, thank you!
    How does the program know that
    Code:
    getline(file, name);
    	getline(file, role);
    	num_of_beast = file.get();
    comes in exactly that order?

    what if you wanted to have the file but only make a call for Role and not for name and beastnumber. How could you specifically call for a particular bit of data from the middle of the document?

    i hope that made sense...

    EDIT: Oh wait, just load all the data into variables, then use the variables you need in the code. Right?

  5. #35
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by kamitsuna View Post
    EDIT: Oh wait, just load all the data into variables, then use the variables you need in the code. Right?
    Generally. If you have a super gigantic database or something, then you may want to deal with it differently. You can also loop thru a file like this (replace the entire part of that last program, from the comment in green, to "return 0") with:
    Code:
    	// if program is still running, the file is ready to read  
    	string buffer;
    	while (getline(file, buffer)) {
    		if (buffer.find("new") != string::npos)
    			cout << buffer << endl;
    	}
    This just prints:

    newbie

    How it works:
    string buffer; -- reusable string variable
    while (getline(file, buffer)) { -- this is the string library getline:
    getline - C++ Reference
    since there is also a fstream getline (which could be used: "file.getline(buffer)", if buffer were a C-string pointer) but it works differently. This one is better for our purposes, because it uses a C++ string, and not a C-string pointer.

    Notice (from that page):
    Parameters
    is
    istream object on which the extraction operation is performed.
    str
    string object where the extracted content is stored.
    delim
    The delimiting character. The operation of extracting succesive characters is stopped when this character is read.

    Return Value
    The same as parameter is.
    Now, I am brand new to C++, but I understand C pretty well, and I am pretty sure this means that when "file" is over, a getline() on "file" is too. I tested this and it's true. So this loop keeps going until there are no more lines to get from the file.

    if (buffer.find("new") != string::npos) -- buffer is a string object, so it includes:
    find - C++ Reference

    A big aside (relax...I'm sorry...bare with me): HIERARCHIES are a very very very important pattern in computer programming.

    HIERARCHY

    Etymology: Middle English ierarchie rank or order of holy beings, from Anglo-French jerarchie, from Medieval Latin hierarchia, from Late Greek, from Greek hierarchēs
    Date: 14th century

    1 : a division of angels
    2 a : a ruling body of clergy organized into orders or ranks each subordinate to the one above it; especially : the bishops of a province or nation b : church government by a hierarchy
    3 : a body of persons in authority
    4 : the classification of a group of people according to ability or to economic, social, or professional standing; also : the group so classified
    5 : a graded or ranked series <a hierarchy of values>
    Now, obviously a hierarchy in programming is #5, but I wanted to include this because it is actually a complex concept, and this definition illustrates it, because it is a hierarchy!

    #1: The angels. (that's nothing to do with computers...)
    #2: the clergy. (nope...)
    #3: people who are authorities (nope...)
    #4: the "classification" of people generally (nope...)
    #5: a graded or ranked series <a hierarchy of values> (this is it)

    Do you see how this is a graded or ranked series (from angels, to priests, to people, to our abstract concept)? Here's another one:

    Code:
    size_t find ( const string& str, size_t pos = 0 ) const;
    size_t find ( const char* s, size_t pos, size_t n ) const;
    size_t find ( const char* s, size_t pos = 0 ) const;
    size_t find ( char c, size_t pos = 0 ) const;
    The way find() works depends how you call it. The definition which applies to
    buffer.find("new")
    will most likely be the third one. Notice, we do not have to supply a second argument -- it is "by default" set to 0. Also notice: find returns a "size_t" value.

    Before I go on, please remember: HIERARCHIES are a very very very important pattern in computer programming. Maybe it seems abstract to you now, but keep the idea in the back of your mind. Also: neither of those hierarchies is ranked top to bottom -- the "ranking" is applied to the list (in this case, in terms of applicable meanings). The red one completes the hierarchy.

    Okay. size_t is a unsigned int type. That is, a whole number >= 0.
    Return Value
    The position of the first occurrence in the string of the searched content.
    If the content is not found, the member value npos is returned.
    It turns out (I tested this ) npos is a string object const member, and we can use it to check and see if any content was found -- it's defined as -1, which is not an unsigned value >= 0. Guess what happens? Because size_t is unsigned, npos becomes the highest possible unsigned int (which is way bigger than any number which could be a position in our string). Hopefully I'll be able to explain why that is when I explain why num_of_beast != 54 ...but enough for now.

    Hopefully the rest just makes sense.
    Last edited by MK27; 02-26-2010 at 07:47 PM. Reason: left string:: off npos
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  6. #36
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by kamitsuna View Post
    How does the program know that
    Code:
    getline(file, name);
    	getline(file, role);
    	num_of_beast = file.get();
    comes in exactly that order?
    Because I knew that and I wrote the program.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  7. #37
    Registered User
    Join Date
    Feb 2010
    Posts
    31
    what i mean is, how does the program know that name is the first line, role is the second line, and beastnumber is the third line?

    Is it because thats the order you wrote the code in?
    If, instead you wrote
    Code:
    num_of_beast = file.get();
    getline(file, role);
    getline(file, name);
    would the first line of the file be read as num_of_beast and the second be "role" and the third be "name" regardless of whats in the file?
    I feel like i'm not capable of expressing my question properly. If the text file was exactly the same
    Code:
    kamitsuna  
    newbie
    666
    then your program would return
    Code:
    num_of_beast = Kamitsuna
    role = newbie
    name = 666
    Does the code just read the file from the top down and you just get what each line is starting from the top.
    Last edited by kamitsuna; 02-26-2010 at 10:01 PM.

  8. #38
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by kamitsuna View Post
    Is it because thats the order you wrote the code in?
    Yes.

    If, instead you wrote
    Code:
    num_of_beast = file.get();
    getline(file, role);
    getline(file, name);
    would the first line of the file be read as num_of_beast and the second be "role" and the third be "name" regardless of whats in the file?
    Almost. This will not happen however:

    then your program would return
    Code:
    num_of_beast = Kamitsuna
    role = newbie
    name = 666
    Because num_of_beast is an int. ints have a fixed size, usually 4 bytes. "kamitsuna" is 9 bytes worth of characters. So something strange will happen if you do that.

    Try it.

    The reason I said "almost" is that after four bytes are read into num_of_beast, there is still more left in the first line. That will go into "role", most likely.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  9. #39
    Registered User
    Join Date
    Feb 2010
    Posts
    31
    yeah, i was hoping to avoid that explaination. I got the integer thing. It was mostly just the concept i was worried about. Thanx for the clarification! Makes more sense to me now

  10. #40
    Registered User
    Join Date
    Feb 2010
    Posts
    31
    I think i understand what the #define function does...but whats the difference between string and define?


    Code:
    // fileread.cpp : Defines the entry point for the console application.
    //
    
    #include "stdafx.h"
    #include <fstream>
    #include <string>
    using namespace std;
    
    // define the filename so it can be changed easily
    #define FILENAME "short.txt"
    string cName;
    string cRoll;
    int num_of_beast;
    
    int main() {
    	cout << "Pick a name: ";
    	cin << cName;
    	cout << "Pick a role: ";
    	cin << cRoll;
    	cout << "What is the number of the beast? ";
    	cin << num_of_beast;
    
    	ofstream fout(FILENAME);
    	fout << cName << endl << cRol << endl << num_of_beast << endl;
    
    	ifstream file(FILENAME);
    	string name, role;
    	int num_of_beast;
    
    	// check if file was opened properly
    	if (file.fail()) {
    		cout << "Could not open " 
    			<< FILENAME
    			<< "! Exiting..." 
    			<< endl;
    		return -1;
    	}
    
    	// if program is still running, the file is ready to read
    	getline(file, name);
    	getline(file, role);
    	num_of_beast = file.get();
    
    	file.close();
                   
    	// now print the data
    	cout << "You: " << name << endl
    		<< "Role: " << role << endl
    		<< "# of the beast: " << num_of_beast
    		<< endl;
    
    	return 0;
    }
    So i wrote a little extra into it. I thought it would get you to input the data real quick, save to a file, then read from the file....but im getting cout errors????
    Im so confused now, cout is so easy and yet im getting errors.

    EDIT: I Commented out my code and it threw errors on your cout too....WTF?
    EDIT EDIT: There is no #include <iostream>! I bet thats why.
    EDIT EDIT EDIT: the include corrected the problem with your cout, but caused HORRIBLE errors with mine...im just going to try to create the file by hand then.
    EDIT EDIT EDIT EDIT: Got your code to run ok, but the int for num_of_beast is returning 54?? You mentioned you knew why, wanna fill me in?
    Last edited by kamitsuna; 02-27-2010 at 03:16 PM.

  11. #41
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    About #define: this is a "preprocessor" command. It replaces a token in your code where-ever it is before it gets compiled. Eg:
    Code:
    #define FILENAME "example.txt"
    #define SOMENUM 666
    You can now use FILENAME anywhere to mean "example.txt" and SOMENUM to mean 666. This makes it easy to change the filename without having to change all the places in the code you use it.

    About errors: sometimes a small mistake (like leaving off a semi-colon) can cause a cascading series of errors. After you put the semi-colon back, all the errors disappear.

    Keep that in mind if you change one line in something and suddenly get lots of bad messages.

    About num_of_beast:

    This is because 666 is stored in the file as text. But an int is not text. So if you made num_of_beast a string and read it in like the other two strings, you could print out 666 -- but you would not be using an int in your code, which if you saved a bunch of data like a character's agility value, you want to have that as an int.

    One way would be to read in a string and then use sscanf:
    Code:
    string buffer;
    getline(file,buffer);
    sscanf(buffer.c_str(),"%d",num_of_beast);
    num_of_beast should now have 666 in it. sscanf() is a standard C i/o function, so you need to #include <cstdio>

    The reason that it was 54 before is that an int is always 4 bytes*, whereas a string representation of a number is of variable length, and the format of the bytes is different than with an int.

    * on most computers
    Last edited by MK27; 02-27-2010 at 04:08 PM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  12. #42
    Registered User
    Join Date
    Feb 2010
    Posts
    31
    gotcha!

    I double checked the code and all my semi colons and stuff seem to be right, its giving me errors out of the string include. Not sure, ill look at it again.

  13. #43
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Post the code if you want. I meant the thing about semi-colons as an example (there are better ones, I just can't think of them).
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  14. #44
    Registered User
    Join Date
    Feb 2010
    Posts
    31
    Code:
    // fileread.cpp : Defines the entry point for the console application.
    //
    #include "stdafx.h"
    #include <iostream>
    #include <ctime>
    #include <string>
    #include <fstream>
    using namespace std;
    
    // define the filename so it can be changed easily
    #define FILENAME "short.txt"
    string cName;
    string cRoll;
    int num_of_beast;
    
    int main() {
    	cout << "Pick a name: ";
    	getline(cin, cName); 
    	cout << "Pick a role: ";
    	getline(cin, cRoll);
    	cout << "What is the number of the beast? ";
    	cin << num_of_beast;
    
    	ofstream fout("FILENAME");
    	fout << cName << endl << cRol << endl << num_of_beast << endl;
    
    	ifstream file(FILENAME);
    	string name, role;
    	int num_of_beast;
    
    	// check if file was opened properly
    	if (file.fail()) {
    		cout << "Could not open " 
    			<< FILENAME
    			<< "! Exiting..." 
    			<< endl;
    		return -1;
    	}
    
    	// if program is still running, the file is ready to read
    	getline(file, name);
    	getline(file, role);
    	num_of_beast = file.get();
    
    	file.close();
                   
    	// now print the data
    	cout << "You: " << name << endl
    		<< "Role: " << role << endl
    		<< "# of the beast: " << num_of_beast
    		<< endl;
    	system("PAUSE");
    	return 0;
    }

  15. #45
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    I think this is just a few typos:

    Code:
    	cout << "What is the number of the beast? ";
    	cin << num_of_beast;
    
    	ofstream fout("FILENAME");
    	fout << cName << endl << cRol << endl << num_of_beast << endl;
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. opening empty file causes access violation
    By trevordunstan in forum C Programming
    Replies: 10
    Last Post: 10-21-2008, 11:19 PM
  2. Can we have vector of vector?
    By ketu1 in forum C++ Programming
    Replies: 24
    Last Post: 01-03-2008, 05:02 AM
  3. Bitmasking Problem
    By mike_g in forum C++ Programming
    Replies: 13
    Last Post: 11-08-2007, 12:24 AM
  4. File Database & Data Structure :: C++
    By kuphryn in forum C++ Programming
    Replies: 0
    Last Post: 02-24-2002, 11:47 AM