Programming Forums

Programming Forums (http://www.programmingforums.org/forumindex.php)
-   C++ (http://www.programmingforums.org/forum15.html)
-   -   Problem opening files (http://www.programmingforums.org/showthread.php?t=12343)

JustAnotherGuy Jan 10th, 2007 12:06 PM

Problem opening files
 
Hello,
I am trying to open a file that the user requests. I have figured out how to open a file that is hardcoded into the program, however like I said I can not seem to get it to work when I want it to open a file that the user requests through something like a "cin" statement.

I have searched the internet for the answer for quite a while now and heeded no good results. I have found multiply different methods but none worked.

EDIT: I am working with a Win32 console application

Thank you, in advance.

kruptof Jan 10th, 2007 12:23 PM

did you make sure that you have double slashes (escape) instead of an single slash:

for example if the user enters "c:\myfile.ext" you need to convert that to "c:\\myfile.ext".

JustAnotherGuy Jan 10th, 2007 12:34 PM

Quote:

Originally Posted by kruptof (Post 122442)
did you make sure that you have double slashes (escape) instead of an single slash:

for example if the user enters "c:\myfile.ext" you need to convert that to "c:\\myfile.ext".

The code I have obtained so far did not seem to need to type in the file location.
one piece of code I found that didn't work:
:

//global
#include <string>
FILE* myFile;
string sname;

//in function
cin >> sname;
myFile = fopen(sname.c_str, "w+b");

When I hard code this though, it works:
:

myFile = fopen("data.txt", "w+b");
It saves the file in the same directory as the project starts from.

ReggaetonKing Jan 10th, 2007 12:48 PM

Where is the namespace std after cin? You have to use std::cin if you don't directly state that you are 'using namespace std'. And also, where is your include statement, cin is located in the iostream header!

:

#include <iostream>
#include <string>
#include <fstream>

int main()
{
        std::string filename, contents = "";
        std::cin >> filename;
        std::ifstream if(file);
        while(std::getline(if, contents))
                contents += contents + "\n";
        //do something with contents
}

I am pretty new to C++ but I think this should compile and work.

DaWei Jan 10th, 2007 12:58 PM

Please read about how to post a good question. It's stuck right at the top of the forum.

That said, are you testing the result of the fopen instruction to see if it failed, and if so, why? You can't open a file that doesn't exist. There are a number of other reasons. Did you test to see if cin worked? Your code doesn't show that.

Information is key. For you, and for your potential respondents. Check for errors. See what they mean. Use output statements to see what various values are. Use a debugger. SHARE that information, when you post, and include enough code so that we can see what you're actually doing.

JustAnotherGuy Jan 10th, 2007 1:12 PM

full code:

:

#include <iostream>
#include <stdio.h>
#include <string>
#include <conio.h>
using namespace std;
int main()
{     
    FILE* myFile;
    int myNumber = 6;
        string sname;

        cout << "enter file name(please include file extension)\n";
        cin >> sname;

    if ((myFile = fopen(sname.c_str(), "w+b")) != NULL) {
        fwrite(&myNumber, sizeof(myNumber), 1, myFile);
        cout << "myNumber is: " << myNumber << endl;
        myNumber = 0;
        cout << "myNumber has been reset to 0." << endl;     
        fclose(myFile);
    }     
    else           
        cout << "Error: File not loaded!" << endl;   
    if ((myFile = fopen(sname.c_str(), "r+b")) != NULL) {
        cout << "Reading previous number from data.txt..." << endl; 
        fread(&myNumber, sizeof(myNumber), 1, myFile);
        cout << "myNumber from data.txt is: " << myNumber << endl;     
    }     
    else
        cout << "Error: File not loaded!" << endl;   

        getch();
    return 0;
}


(I edited the code slightly) I managed to figure out the answer to my first question. I noticed that this now will write the number and than load it fine. however, I need to figure out how to tell it to save a string.

Also, I noticed that what it saves in the text file does not appear to be what it's loading. text file contains simply(yet it manages to load it right):
Is it suppossed to save like that?

DaWei Jan 10th, 2007 1:53 PM

That's not clear, either, but oh well. You're doing things the hard way, too, but let's also ignore that for the moment. If I take the bare bones of your code and clean it up a mere tad, so that it looks like this,
:

#include <iostream>
#include <cstdio>
#include <string>

using std::cin;
using std::cout;
using std::endl;
using std::cerr;
using std::string;

int main (int argc, char *argv [])
{
        FILE *myFile;
        string sname = "data.txt";
        int myNumber = 10;

        if ((myFile = fopen (sname.c_str(), "w+b")) != NULL)
        {
                fwrite (&myNumber, sizeof (myNumber), 1, myFile);
                cout << "myNumber is: " << myNumber << endl;
                myNumber = 0;
                cout << "myNumber has been reset to 0."  << endl;     
                fclose(myFile);
        }     
        else cout << "Error: File not loaded!" << endl;

        if ((myFile = fopen (sname.c_str(), "r+b")) != NULL)
        {
                cout << "Reading previous number from data.txt..." << endl; 
                fread(&myNumber, sizeof(myNumber), 1, myFile);
                cout << "myNumber from data.txt is: " << myNumber << endl;     
        }     
    else cout << "Error: File not loaded!" << endl;

        cin.get ();
        return 0;
}

The output is this,
Quote:

Originally Posted by Output
myNumber is: 10
myNumber has been reset to 0.
Reading previous number from data.txt...
myNumber from data.txt is: 10

Comment?

JustAnotherGuy Jan 10th, 2007 2:20 PM

Well, thank you for your time. By playing with your code a little I managed to solve all my problems.


Thank you again.

DaWei Jan 10th, 2007 2:36 PM

You might want to consider some alternate methods.

SOME WAYS TO OPEN AND USE A FILE

Methods for opening files for reading and writing might be classified as C++, C stream, and C low-level methods. There are numerous variations, particularly with C++ streams; this post can in no way be considered exhaustive. CHECK YOUR DOCUMENTATION.

A NOTE ABOUT MODE

Unix/Linux have only one mode for file operations: binary. Windows has a text mode which is, unfortunately, the default. In text mode, content beyond what you supply is written to the file; it is stripped when you read the file. This makes the use of
random access (seek, tell, etc.), problematic. Even worse, a 'soft' EOF, a special character, is written. This indicator is NOT MOVED if you do an append, so appended data is not reachable unless you reset the EOF indication. Consequently, I recommend always using binary mode. With 'fopen,' you can specify a read or write or other mode as "rb", "wb", etc. Unix/Linux will accept and ignore the 'b', so you can use it portably. You can also set the default mode in Windows with the global variable, _fmode.

C++ USING FSTREAM

VC++ 6.0, Windows XP
Include iostream, fstream, and string for the following examples.

FSTREAM
OPENING FOR WRITE
:


  // Example variables
  string sFileName = "test.txt";
  string sContents = "File data\n";
  string sToken;
  char  lineBuffer [256];
  int    nCount = 0;

  // Construct an fstream object and attempt to open
  // for output
  fstream ooFile;
  ooFile.open (sFileName.c_str (), ios::binary | ios::out);

  // Test for success
  if (!ooFile.is_open ()) return badHappenstance ("Couldn't open file for writing");

  // Write example
  ooFile << sContents;

  // Test the write for success
  if (!ooFile.good ()) return badHappenstance ("Write failed");

  // Close the file.  Note that the file will be closed automatically when
  // the object is destroyed (goes out of scope).
  ooFile.close ();


OPENING FOR READ
:


  // Open it for input
  ooFile.open (sFileName.c_str (), ios::binary | ios::in);
  if (!ooFile.is_open ()) return badHappenstance ("Couldn't open file for reading");

  // Read tokens until end of file or error
  while (ooFile.good ())
  {
      ooFile >> sToken;
      cout << "Token " << ++nCount << ": ";
      if (sToken.size ()) cout << sToken; else cout << "(null token)";
      cout << endl;
  }
  // Check some status for grins
  if (ooFile.eof ()) cout << "Reached EOF" << endl;
  else if (ooFile.fail ()) return badHappenstance ("Read failed for some reason");

  // Alternatively, read entire line
  ooFile.getline (lineBuffer, sizeof (lineBuffer));

  // Always the status
  if (!(ooFile.good () || ooFile.eof ()))
      return badHappenstance ("Failure reading line");

  cout << "This is the line: " << lineBuffer << endl;


A SEEK EXAMPLE
:


  // Position to beginning after clearing EOF or fail bits
  ooFile.clear ();
  ooFile.seekg (0, ios::beg);
  if (!ooFile.good ()) return badHappenstance ("Seek failed");

  ooFile.close ();


Example output:
Quote:

Token 1: File
Token 2: data
Token 3: (null token)
Reached EOF
This is the line: File data
C USING FOPEN

Include stdio.h for this method.

OPENING FOR WRITE
:


  // Example variables
  FILE *ooFile;
  char  sFileName [] = "test.txt";
  char  sContents [] = "File data\n";
  char  sToken [32];
  char  lineBuffer [256];
  int  nCount = 0;
  int  status;

  // Attempt to open file for output
  ooFile = fopen (sFileName, "wb");

  // Test for success
  if (!ooFile) return badHappenstance ("Couldn't open file for writing");

  // Write the contents
  status = fputs (sContents, ooFile);

  // Test for success
  if (status == EOF) return badHappenstance ("Write failed");

  // Close the file
  fclose (ooFile);


OPENING FOR INPUT
:


  ooFile = fopen (sFileName, "rb");
  if (!ooFile) return badHappenstance ("Couldn't open file for reading");

  // Read tokens until end of file or error -- one method: fscanf
  // fscanf consumes whitespace, unlike some C++ methods
  // so there won't be a null token at the end.
  while (1)
  {
      if (fscanf (ooFile, "%s", sToken) != 1)
      {
        if (feof (ooFile))
        {
            printf ("Reached EOF\n");
            break;
        }
        else return badHappenstance ("Failed to read token");
      }
      printf ("Token %d: %s\n", ++nCount, sToken);
  }
// REPOSITIONING EXAMPLE

  rewind (ooFile);

  // Read a line all in one swell foop
  // We'll either fill the buffer or have a newline
  // at the end of the buffer, or both.  If you don't
  // want the newline:
  //
  //    index = strlen (lineBuffer) - 1;
  //    if (lineBuffer [index] == '\n')
  //        lineBuffer [index] = '\0';"
  //
  if (fgets (lineBuffer, sizeof (lineBuffer), ooFile) == NULL)
      // Always the status; EOF is okay, error is not
      if (ferror (ooFile)) return badHappenstance ("Failed to read line");

  printf ("This is the line: %s", lineBuffer);
  fclose (ooFile);


Example output:
Quote:

Token 1: File
Token 2: data
Reached EOF
This is the line: File data
C USING LOW LEVEL _open

As far as I'm concerned, low level file operations are only good for reading large amounts of binary data, and are not necessary for that. One is far better off using the higher level functions.

VC++ 6.0, Windows XP
Include stdio.h, io.h, fcntl.h, sys\stat.h, ctype.h, and string.h for the following example.

OPENING FOR READ/WRITE
:


typedef int fileHandle;
extern int errno;

  // Example variables
  fileHandle ooFile;
  char  sFileName [] = "test.txt";
  char  sContents [] = "File data\n";
  char  sToken [32];
  char  sTrash [32];
  char  lineBuffer [256];
  int  nChars, nTokens;
  int  status;

  // Attempt to open file for input/output
  ooFile = _open ("test.txt", _O_CREAT | _O_RDWR | _O_TRUNC | _O_BINARY, _S_IWRITE);

  // Test for success
  if (ooFile == EOF) return badHappenstance (strerror (errno));


WRITING
:


  // Write the contents
  status = _write (ooFile, sContents, strlen (sContents));

  // Test for success
  if (status == EOF) return badHappenstance ("Write failed");


SEEK AND READ OPERATION -- Far more complex than higher level methods
:


  // Return to the beginning for input
  if (_lseek (ooFile, 0, SEEK_SET) == -1L)
      return badHappenstance ("Seek to beginning failed");

  // Read tokens until end of file or error
  nTokens = 0;
  while (1)
  {
      // Skip any whitespace
      while (status = _read (ooFile, sTrash, 1) == 1)
        if (!isspace (sTrash [0])) break;
      // Check for EOF or failure
      if (status < 0) return badHappenstance ("Failure to read data");
      else if (status == 0) break;
      sToken [0] = sTrash [0];
      for (nChars = 1; nChars < sizeof (sToken) - 1; nChars++)
      {
        status = _read (ooFile, &sToken [nChars], 1);
        // Check for EOF or failure
        if (status < 0) return badHappenstance ("Failure in reading data");
        else if ((status == 0) || (isspace (sToken [nChars])))
        {
            sToken [nChars] = '\0';
            break;
        }
      }
      // The token could be too long...
      if (nChars >= sizeof (sToken) - 1)
      {
        sTrash [0] = ' ';
        // Skip any remaining non-whitespace characters
        while (status = _read (ooFile, sTrash, 1) == 1)
            if (!isspace (sTrash [0])) break;
        // Check for EOF or failure
        if (status < 0) return badHappenstance ("Failure in reading data");
        else if (status == 0) break;
      }
      // Or we could have completed the token
      if (strlen (sToken) > 0) printf ("Token %d: %s\n", ++nTokens, sToken);
  }
  printf ("End of file\n");

  // Reposition to beginning
  if (_lseek (ooFile, 0, SEEK_SET) == -1L)
      return badHappenstance ("Seek to beginning failed");

  // Read one buffer's worth
  status = _read (ooFile, lineBuffer, sizeof (lineBuffer) - 1);
  if (status > 0)
      lineBuffer [status] = '\0';

  printf ("This is the line: %s", lineBuffer);
  _close (ooFile);

  return 0;
}


Example output:
Quote:

Token 1: File
Token 2: data
End of file
This is the line: File data


All times are GMT -5. The time now is 1:40 AM.

Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC