Thread: File Directories using I/O

  1. #1
    Student legit's Avatar
    Join Date
    Aug 2008
    Location
    UK -> Newcastle
    Posts
    156

    File Directories using I/O

    Hey guys and gals!
    I've got good news, my File Manager is working! Feels great when systems work anyways... I now have a problem in reading from files that I have put in a certain Directory... Lemmi explain:

    I can read from them perfectly fine if they are in the same directory as my code, but when I put the "Magic.txt" and the "Combat.txt" in a character folder, my error system tells me that I am unable to open these files. So my question is:

    How can I read from and write to files in a certain directory?

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    How exactly are you opening the files?

    Are you using a relative or absolute path? If relative, where is 'home'?

    What is the actual error message (or error number), we need more than "it doesn't work".

    Maybe a few snippets of relevant code.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Student legit's Avatar
    Join Date
    Aug 2008
    Location
    UK -> Newcastle
    Posts
    156
    Quote Originally Posted by Salem View Post
    How exactly are you opening the files?

    Are you using a relative or absolute path? If relative, where is 'home'?

    What is the actual error message (or error number), we need more than "it doesn't work".

    Maybe a few snippets of relevant code.
    I'm opening the files using file I/O, i'll post the code, maybe it will be easier:

    FileMgr.h:
    Code:
    #ifndef FileMgr_h /*inclusion guards*/
    #define FileMgr_h
    
    class FileMgr
    {
    public:
    	FileMgr(); /*Constructor*/
    	virtual ~FileMgr(); /*Virtual Destructor*/
    	void vSetFileName(char*); /*Function for setting the filename*/
    	void vClearFileNameBuffer(); /*Function for clearing the filename*/
    	char *cGetFileName() const; /*Function pointer to aqcuire the file name*/
    	void vReadFromFile(); /*Function for reading the contents of a file*/
    protected:
    	char *m_cFilename; /*protected member variable*/
    };
    
    #endif
    FileMgr.cpp
    Code:
    #include <iostream>
    #include <fstream>
    #include "FileMgr.h"
    /*Function Definitions*/
    
    FileMgr::FileMgr():m_cFilename(0) /*Constructor initialization list*/
    {
    }
    
    FileMgr::~FileMgr() /*Destructor definition*/
    {
    	m_cFilename = 0; /*Just incase we forget to clear the filename before the program ends*/
    }
    
    void FileMgr::vSetFileName(char *cFilename)
    {
    	m_cFilename = cFilename; /*Assigns the contents of cFilename to m_cFilename*/
    	cFilename = 0; /*Assigns cFilename to NULL for safety*/
    }
    
    void FileMgr::vClearFileNameBuffer()
    {
    	m_cFilename = 0; /*Assigns m_cFilename to NULL, so we can use it again*/
    }
    
    char *FileMgr::cGetFileName() const
    {
    	return m_cFilename; /*Returns member variable to the program*/
    }
    
    void FileMgr::vReadFromFile()
    {
    	char ch; /*Character for reading contents of file*/
    	std::ifstream iFile(m_cFilename); /*Create an ifstream object for opening a file for output*/
    	if(!iFile.is_open()) /*Checks if the file can be opened*/
    	{
    		std::cout << "Error! Unable to open " << m_cFilename << "..." << std::endl; /*If it can't, output this*/
    	}
    	else /*Otherwise...*/
    	{
    		while(iFile.get(ch)) /*Read the characters from the file*/
    		{
    			std::cout << ch; /*Output the file contents to the console*/
    		}
    		std::cout << std::endl; /*Output a new line to the console after file contents is read*/
    	}
    	iFile.close(); /*Close the file after it's purpose has bin fullfilled*/
    }
    This is my file manager system, hope this helps :S

  4. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    I don't think this answers any of the questions. I still have no idea if you're using absolute or relative paths, nor the error message/number generated by the failed call.

    You should also note that this:
    Code:
    cFilename = 0; /*Assigns cFilename to NULL for safety*/
    doesn't do jack. (Changes to passed-in variables are discarded at the end of a function.)

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > m_cFilename = cFilename;
    You've basically broken the single most important rule of data encapsulation, which C++ classes are there to solve.

    Something inside your class POINTS to something outside your class.

    If the thing you're pointing at gets deallocated, your class has no chance at that point.

    Stop mucking about with overly optimised char pointers would be my suggestion, and use std::string
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #6
    Student legit's Avatar
    Join Date
    Aug 2008
    Location
    UK -> Newcastle
    Posts
    156
    Quote Originally Posted by Salem View Post
    > m_cFilename = cFilename;
    You've basically broken the single most important rule of data encapsulation, which C++ classes are there to solve.

    Something inside your class POINTS to something outside your class.

    If the thing you're pointing at gets deallocated, your class has no chance at that point.

    Stop mucking about with overly optimised char pointers would be my suggestion, and use std::string
    Yeah I tried that first, but std::string isn't supported by File I/O yes?

    EDIT:
    But cFilename is a local variable for the function that belongs to my class, so technically it's in class scope? Just a thought, I'm probably wrong.

    EDIT #2:
    Quote Originally Posted by tabstop View Post
    I don't think this answers any of the questions. I still have no idea if you're using absolute or relative paths, nor the error message/number generated by the failed call.
    What do you mean by absolute or relative? And I don't get a compiler error, but I can't open the file, which I've told my program to tell me to do so if I can't... misunderstanding
    Last edited by legit; 06-16-2009 at 01:26 AM.

  7. #7
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    So you should be storing strings and using the .c_str() inside your constructors then.

    Are you unable to google "absolute path" or "relative path"?

    If a function call like fopen fails, you can get more information from errno about what the OS says the problem is. You can do print strerror(errno) if the open fails to get a message. (You may need to include <errno.h>.)

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > Yeah I tried that first, but std::string isn't supported by File I/O yes?
    What do you mean?

    The only conspicuous place where you need a char array is where you open the file.
    And that's easy to achieve like this
    Code:
    // m_cFilename is now a std::string
    std::ifstream iFile(m_cFilename.c_str());
    Keep everything as a std::string.
    Use the c_str() method when you absolutely need to.

    When reading character data from some historic interface, convert it to std::string as soon as possible.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  9. #9
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    strerror() is POSIX. You can use perror() to get the same information in an ANSI-C89 compatible way (if you don't mind always printing to stderr). Also, I'm not sure whether these functions will work with C++ file streams instead of C functions like fopen().
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  10. #10
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by dwks View Post
    strerror() is POSIX. You can use perror() to get the same information in an ANSI-C89 compatible way (if you don't mind always printing to stderr). Also, I'm not sure whether these functions will work with C++ file streams instead of C functions like fopen().
    strerror is in POSIX, but it is also in C99 and according to an internet search was also in C89. This is supported by the fact that it appears in the C++ standard as part of the <cstring> header.

  11. #11
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Wow, you're right. strerror() is C89. That's extremely strange; I even did a "man strerror" when I posted, and I thought it said POSIX. I must have misread it somehow . . . .

    Is errno C89 then too?
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  12. #12
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by dwks View Post
    Is errno C89 then too?
    Yes.

    Sometimes the docs say "Posix" because it is ALSO part of the Posix standard, or because there are extensions on the same man-page that are Posix only.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  13. #13
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Interesting. And what I meant was, the docs make it quite clear that strerror() is C89, but my eye must have skimmed down a few paragraphs where they talk about POSIX. Or something.
    Code:
    CONFORMING TO
           strerror() is specified by POSIX.1-2001,  C89,  C99.   strerror_r()  is
           specified by POSIX.1-2001.
    
           The GNU-specific strerror_r() function is a non-standard extension.
    
           POSIX.1-2001  permits strerror() to set errno if the call encounters an
           error [...]
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Data Structure Eror
    By prominababy in forum C Programming
    Replies: 3
    Last Post: 01-06-2009, 09:35 AM
  2. File I/O Assertion Failure in VS2008
    By clegs in forum C Programming
    Replies: 5
    Last Post: 12-25-2008, 04:47 AM
  3. Game Pointer Trouble?
    By Drahcir in forum C Programming
    Replies: 8
    Last Post: 02-04-2006, 02:53 AM
  4. Unknown Memory Leak in Init() Function
    By CodeHacker in forum Windows Programming
    Replies: 3
    Last Post: 07-09-2004, 09:54 AM
  5. advice on file i/o
    By Unregistered in forum C Programming
    Replies: 1
    Last Post: 11-29-2001, 05:56 AM