void openfile(const string &db_filename) {
ifstream file;
file.open("db_filename");
if(file.is_open())
{
cout<<"true"<<endl;
}
else cout<<"false"<<endl;}
I have this simple code here that checks if file is open. However, whenever I run this, I get false. which means that the file is not open. I dont know why but Im sure that the files are in the same folder and the file name is entered correctly. Is there anything wrong with this code?
You are passing a string literal "db_filename" to open() instead of passing your db_filename string object. Simply remove the quotes:
file.open(db_filename);
If your version of the STL doesn't support passing a std::string to open(), call the string's c_str() method instead:
file.open(db_filename.c_str());
Related
Need help fixing my code, not sure what's wrong. I'm using C++11, trying to write a vector to a file by individually writing each struct. The section of code returning an error is:
string craigSave = "craigSave.txt";
ofstream file(craigSave.c_str());
file.open("craigSave.txt");
for (int i=0; i<finalVector.size(); i++){
file << finalVector[i]<<endl;
}
file.close("craigSave.txt");
cout<<"Thanks for shopping!"<<endl;
done = true;
The error returned is on the "file.close" line and is:
error: no matching function for call to 'std::basic_ofstream::close(const char [14])'
I research on this error seems to point to needing to use char* as an argument instead of a string, but I'm using C++11, so it should accept strings. Also it is strange that there is no error for the file.open line, as all research shows the error being there, not at file.close
Just use file.close();, there's no need to pass the file name again.
See http://www.cplusplus.com/reference/fstream/ofstream/close/.
Also, ofstreams are RAII objects, which means that the file will automatically be closed once the ofstream object goes out of scope (see do I need to close a std::fstream?):
{
ofstream out("name");
// do something with out...
} // out.close is called automatically
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I am using following function:
int getline_count()
{
boost::smatch resultc;
string sLine;
int line_add_tmp;
ifstream infile;
infile.open("scripts.txt", ios_base::in);
if (!infile){
cerr << "scripts.txt could not be opened!" << endl;
}
else {
getline(infile, sLine);
if (boost::regex_match(sLine, c)) {
line_add = 2;
}
else {
line_add = 1;
}
return line_add;
infile.close();
}
}
Intension for the above function is to test if the first line in the file contains '// new' If true, 2 is returned. If false, 1 is returned. This works fine so far.
What I am confused about is that after the run the file scripts.txt is empty. How can that be since
1.) The '// new' line was correctly identified as I am getting '2' returned (running on an empty file returns 1 as expected). So it can't be that during opening the file scripts.txt it was overwritten with an empty file
2.) ifstream was designed to read only
What is it what I am missing?
Edit:
Definition for c is
static const boost::regex
c("^(\\/)(\\/)(new|New| new| New)"); // Regexp for line count
An ifstream should never manipulate your file. You will need to look elsewhere for your problem, it's not inside this code. Your best bet is to provide a Minimal, Complete, and Verifiable example that demonstrates your problem.
However, you should check your coding, you are missing essentials like error handling and treating compiler warnings. Most likely, if your other code looks the same, that's the source of your problem.
Personally, I'd write your function like this:
bool first_line_in_file_matches(const std::string& filename, const boost::regex& c)
{
std::string line;
std::ifstream infile(filename.c_str());
if (!infile)
{
cerr << filename << " could not be opened!" << endl;
// TODO: THROW AN EXCEPTION MAYBE? OR RETURN FALSE? EXIT HERE
}
return getline(infile, line) && boost::regex_match(line, c);
}
This function will not clear the contents of the file. So if in fact the file is cleared it is cleared externally to getline_count.
To prove this lets inspect the functionality of each call on ifstream relative to the file:
ifstream::open This will only clear the file if the mode is set to ios_base::trunk
ifstream::operator bool This is a const method so the ifstream cannot be modified
ifstream::getline TLDR: This can only extract, not write to a file:
Internally, the function accesses the input sequence by first constructing a sentry object (with noskipws set to true). Then (if good), it extracts characters from its associated stream buffer object as if calling its member functions sbumpc or sgetc, and finally destroys the sentry object before returning.
ifstream::~ifstream This is implicitly declared, so it simply destroys the object, closing the file; if this deleted file contents no one would ever have been able to use an ifstream
The recommended steps to finding the culprit of the file clearing are:
Ensure that you are looking at the correct file and don't have some process external to your code which is clearing the file
Search your code for "scripts.txt" something else has to access the file by name and debug it
Disable writing to "scripts.txt" and see if you can locate the code that fails to write to the file
I have this code
{
char *filename = createFilename(file, extension);
...
...
delete[] filename;
}
inline char *DataSet::createFilename(LPCSTR file, LPCSTR extension)
{
char *path = new char[strlen(file) + strlen(extension) + 1];
strcpy(path, file);
strcat(path, extension);
return path;
}
Am I right to delete "filename" in the main function? I get ERROR_INVALID_NAME on delete. I have checked the filename and that is correct.
I know I should be using std::string but this is existing code. Please help
If it's existing code and you can't change createFilename to return a std::string, then how about changing the call site to use std::unique_ptr. It is specialized for arrays and would be a much safer bet than doing delete on your own. See this answer.
An error of type ERROR_INVALID_NAME usually occurs when the directory name, file name or volume label is incorrect. On Windows, you might have to take care of escape sequences. For example, if the path to the file is C:\Folder\File.ext you should use the string C:\\Folder\\File.ext. In addition, some characters may not be accepted by the API you're using even though Windows allows them to be used in file and directory names. See this.
For the following code:
fstream file("file.txt", ios::in):
//some code
//"file" changes here
file.close();
file.clear();
file.open("file.txt", ios::out | ios::trunc);
how can the last three lines be changed so that the current file is not closed, but "re-opened" with everything blanked out?
If I am understanding the question correctly, you'd like to clear all contents of the file without closing it (i.e. set the file size to 0 by setting EOF position). From what I can find the solution you have presented is the most appealing.
Your other option would be to use an OS-specific function to set the end of file, for example SetEndOfFile() on Windows or truncate() on POSIX.
If you're only looking to begin writing at the beginning of the file, Simon's solution works. Using this without setting end of file may leave you in a situation where you have garbage data past the last position you wrote though.
You can rewind the file: put back the put pointer to the beginning of the file, so next time you write something, it will overwrite the content of the file.
For this you can use seekp like this:
fstream file("file.txt", ios::in | ios::out); // Note that you now need
// to open the file for writing
//some code
//"something" changes here
file.seekp(0); // file is now rewinded
Note that it doesn't erase any content. Only if you overwrite it so be careful.
I'm guessing you're trying to avoid passing around the "file.txt" parameter and are trying to implement something like
void rewrite( std::ofstream & f )
{
f.close();
f.clear();
f.open(...); // Reopen the file, but we dont know its filename!
}
However ofstream doesn't provide the filename for the underlying stream, and doesn't provide a way to clear the existing data, so you're kind of out of luck. (It does provide seekp, which will let you position the write cursor back to the beginning of the file, but that wont truncate existing content...)
I'd either just pass the filename to the functions that need it
void rewrite( std::ostream & f, const std::string & filename )
{
f.close();
f.clear();
f.open( filename.c_str(), ios::out );
}
Or package the filestream and filename into a class.
class ReopenableStream
{
public:
std::string filename;
std::ofstream f;
void reopen()
{
f.close();
f.clear();
f.open( filename.c_str(), ios::out );
}
...
};
If you're feeling over zealous you could make ReopenableStream actually behave like a stream, so that you could write reopenable_stream<<foo; rather than reopenable_stream.f<<foo but IMO that seems like overkill.
First of all, i'd to establish that i do have the text file in my Folders directory. Im using visual studio and it is where my source code is compiling.
The code below should demonstate why its not working. In visual studio.
int main( const int argc, const char **argv )
{
char usrMenuOption;
const char *cFileName = argv[ 1 ];
checkName( cFileName ); // supplying the checkName function with contents of argv[1]
usrMenuOption = getUsrOption(); // calling another function
fgetc(stdin);
return 0;
}
ifstream *openInputFile( const char *cFileName )
{
// this function might be the pronblem.
ifstream *inFile;
inFile = new ifstream;
inFile->open( cFileName, ios::in );
return inFile;
}
bool checkName( const char *cFileName )
{
// it works fine if i use a regular ifstream obj and not the one from the function
ifstream *inFile;
inFile = openInputFile( cFileName );
inFile->open( cFileName, ios::in );
if ( inFile->good() )
{
return true;
}
else
{
cout << '"' << cFileName << '"' << ": File does not exist! " << endl;
return false;
}
}
It does work if i use a non-pointer object for the ifstream.
however i need to open all of my input files this way, using the function i made.
I'm a little confused because i did not have this issue compiling in dev-cpp
You have a few options:
The one you've tried - opening the file.
Using stat.
Using GetFileAttributes.
Using FindFirstFile.
The only way to guarantee that it exists and that you can use it is to open it. If you use other methods you end up with a race condition (because the file could be deleted or locked after you check to see if it exists.
EDIT: You have a couple of other issues in your code. Firstly, you allocate a infile via new, but you never delete it. Secondly, you call open twice.
That's a poor way to test for existence: because if the file is open by another process, then the file exists but you can't open it.
A better way to test might be to use the GetFileAttributes Function: if it doesn't return INVALID_FILE_ATTRIBUTES then the file exists.
If you don't mind using Boost, there is a simple function boost::filesystem::exists( path ) that would be useful to you I guess !
I always check ifs.is_open() where ifs is a ifstream.
To check for the existence of a file (POSIX.1 compliant):
#include <unistd.h>
if (! access (file_name, F_OK))
{
// File exists.
}
How do i check if a file exists using ANSI C++?
#include <fstream>
inline bool FileExists(const char * filename)
{
return std::ifstream(filename);
}
You're trying to open the file twice inside checkName(): the first time in the constructor call inside the call to openInputFile(), the second time inside checkName() itself. Why the second call to open()?
I don't know what happens when an ifstream with an already-open file attempts to open() another file, but it won't be good, and it may well depend on the exact library implementation (hence the different behaviour between Dev-C++ and MSVC++). In short, don't do it.
There is at least one other bug: You aren't closing inFile anywhere inside checkName().
But Anyway, Do This Instead
Really, it's better not to have a separate checkName() function -- just have openInputFile() attempt to open the file, and if it fails, report the error right there and/or return a NULL pointer (or even throw an exception). That way, the operation is "atomic" -- as things stand, if the file exists at the time checkName() is called but is deleted before a subsequent call to openInputFile(), your code will get very confused.