How to clear a file using FILE* - c++

I am developing a study project. It includes registration, authorization, and saving records of customer. In my project reading the information from file using fstream is not working so I use FILE* method. And I need to clear all data in file to rewrite it for saving new records.
There is a question. How to clear it? I found a lot of examples how to do this but all of their are for using fstream. Is it real to do using FILE* ?
Here is some code:
FILE* Usrs = fopen("Users.dat", "rb");
StructForReg Array[100];
StructForReg Perenos;
int i = 0;
while (!!(feof(Usrs) == 0))
{
fread(&Perenos, sizeof(StructForReg), 15, Usrs);
Array[i] = Perenos;
i += 1;
}
fclose(Usrs);
//here must be a code with clearing and rewriting

How to clear a file using FILE*?
And I need to clear all data in file to rewrite it for saving new records.
Just open with using "w" (or "wb") mode. From cppreference the w mode destroys file contents if the file exists. If the file does not exists, it will create a new one.

See the manpage for fopen. "w" or "w+" in the flags causes the file to get truncated.

Related

How to writte a file in c++, considering that everytime you run the code, the file keeps storing the previous data?

I'm working in creating a file that contains the data that describes the position of a cell in fuction of time. I was adviced to use snprintf. These were the lines of code that I used to introduce the function:
int n_sample = 50;
char filename[101];
snprintf(filename, sizeof(filename),"dados_movimento_celula_%d.dat", n_sample);
The code runs, showing no errors, however, it keeps alterating the file by replacing the previous data with the new one, instead of just adding the new one set of data. How to fix this?
You can use ofstream and open the file in append mode:
std::ofstream outFile;
outfile.open(fileName, std::ios_base::app);
outFile << content;

Why must the file exist when using the 'r+' mode in fopen?

Why add this constraint when your intentions are to both read and write data to the file?
My application wants to open the file in both reading an writing mode. If I use w+ it will destroy the previous contests of the file, but at the same time it will create the file if it doesn't exist.
However if I use the r+ mode, my application will work properly, but if the file doesn't exist it will throw an exception about the nonexistence of the file.
Try something like this. If the first fopen fails because the file does not exist, the second fopen will try to create it. If the second fopen fails there are serious problems.
if((fp = fopen("filename","r+")) == NULL) {
if((fp = fopen("filename","w+")) == NULL) {
return 1;
}
}

Replacing a file with another file but keeping the file the same name.

My programming knowlege is very limited so please take this into account when reading this. I am using Visual C++ MFC and I am looking for a basic function that would overwrite the contents of a file but keep the file the same name. I am sure this is probably fairly simple however I can't seem to find anything online. Thanks in advance for any help.
You can use CFile::Open() there is flags to specify to open an existing file without truncating it. For example if you want to create the file if it not exists, or using the alreading existing without truncating you can use CFile::modeCreate|CFile::modeNoTruncate. You can then seet to the needed position by using CFile::Seek()
It's been a while since I've done any MFC work so I'll just give you the general standard on how to do this in C/C++. This will give you a direction on how to work with MFC.
When you're opening a file, you can choose an "open flag" that tells the file system how to open it. it can be "a" for append, "r" for read, "w" for write over (trunacte), and you can add "b" if it's a binary file.
so to do that just do:
FILE *fp = fopen("my_file.whatever", "wb");
if (fp)
{
//now write to
the file... ....
fclose(fp);
}

Force read on disk with std::ifstream instead of the file cache

I have a program that load data from a file using std::ifstream and store the data in a structure. After that, I verify if the data I want was in the file. If it is not, I ask the user to modify the file and press a key. I then reload the file. The problem is that even if the user modified the file, I always get the same data in the file because the file seems to be cache in the application. I've seen that in win32 API, it's possible to use the flag FILE_FLAG_NO_BUFFERING to avoid using a buffered copy when reading a file, but I would like to use that feature with std::ifstream. Is there any way to use the handle created through win32 api with ifstream or anyway to force it directly in std::ifstream ?
Here's a "simplified" code sample:
SomeStructure s = LoadData(fileName);
while(!DataValid(s))
s = LoadData(fileName);
SomeStructure LoadData(const std::string& fileName)
{
std::ifstream fileStream;
while(!OpenFileRead(fileName, fileStream))
{
std::cout<<"File not found, please update it";
fileStream.close();
//Wait for use input
std::string dummy;
std::getline(std::cin, dummy);
}
//... Read file, fill structure, and return
std::string line;
while(std::getline(fileStream, line) && line!="")
{
//At this point, I can see that line is wrong
StringArray namedatearray=Utils::String::Split(line, "|");
assert(namedatearray.size()==2);
//Add data to my structure ( a map)
}
fileStream.close();
//return structure
}
bool OpenFileRead(const std::string& name, std::fstream& file)
{
file.open(name.c_str(), std::ios::in);
return !file.fail();
}
Thanks.
Edit: Of course, it was a mistake because I had two time the same file in two very similar path. Looking at the handle of the file open with process explorer (and not the relative file path made me found it).
Instead of thinking that this is due to some kind of "buffering", I would look for the obvious things first.
Are you sure the user is changing the same file that you're reading?
Are you certain reloading the data is properly updating your data structure in memory?
Are you confident that DataValid() is doing what you want?
The fact that the OS uses file buffers to increase disk performance is generally not visible from the application level. As long as you're looking at the same file, the OS knows that the user updated the file, and if you reopen it, then you'll see the changed data. If the data never even had a chance to get flushed to disk, that won't affect your application.

How to create a temporary text file in C++?

I'm trying to create a temporary text file in C++ and then delete it at the end
of the program. I haven't had much luck with Google.
Could you tell me which functions to use?
The answers below tell me how to create a temp file. What if I just want to
create a file (tmp.txt) and then delete it? How would I do that?
Here's a complete example:
#include <unistd.h>
int main(void) {
char filename[] = "/tmp/mytemp.XXXXXX"; // template for our file.
int fd = mkstemp(filename); // Creates and opens a new temp file r/w.
// Xs are replaced with a unique number.
if (fd == -1) return 1; // Check we managed to open the file.
write(fd, "abc", 4); // note 4 bytes total: abc terminating '\0'
/* ...
do whatever else you want.
... */
close(fd);
unlink(filename); // Delete the temporary file.
}
If you know the name of the file you want to create (and are sure it won't already exist) then you can obviously just use open to open the file.
tmpnam and tmpfile should probably be avoided as they can suffer from race conditions - see man tmpfile(3) for the details.
Maybe this will help
FILE * tmpfile ( void );
http://www.cplusplus.com/reference/clibrary/cstdio/tmpfile/
Open a temporary file
Creates a temporary binary file, open
for update (wb+ mode -- see fopen for
details). The filename is guaranteed
to be different from any other
existing file. The temporary file
created is automatically deleted when
the stream is closed (fclose) or when
the program terminates normally.
See also
char * tmpnam ( char * str );
Generate temporary filename
A string containing a filename
different from any existing file is
generated. This string can be used to
create a temporary file without
overwriting any other existing file.
http://www.cplusplus.com/reference/clibrary/cstdio/tmpnam/
This may be a little off-topic because the author wanted to create a tmp.txt and delete it after using it, but that is trivial - you can simple open() it and delete it (using boost::filesystem of course).
mkstemp() is UNIX-based. With Windows you use GetTempFileName() and GetTempPath() to generate a path to a temp file. Sample code from MSDN:
http://msdn.microsoft.com/en-us/library/aa363875%28VS.85%29.aspx
On Linux (starting with kernel 3.11), there's flag to open(2) O_TMPFILE that creates a temporary file that doesn't have a name (i.e. it doesn't show up in the filesystem). This has a few interesting features:
No worries about unique names, it's just an inode, there is no name.
No race conditions during creation (e.g. symlink attacks).
No stray files if your app crashes, it's always automatically deleted.
I wonder why most of you guys showed him the C way of doing it instead of the C++ way.
Here's fstream.
Try that, deleting a file is OS depended but you can use boost.filesystem to make things easy for you.
If you need a named file (for example, so you can pass the name to another process, perhaps a compiler or editor), then register a cleanup function that removes the file with atexit(). You can use either C++ <iostream> or C FILE * (<cstdio>) to create the file. The not completely standard but widely available mkstemp() function creates a file and tells you its name as well as returning a file descriptor (a third I/O mechanism); you could use the fdopen() function to convert the file descriptor into a FILE *.
If you don't need a named file a C-style FILE * is OK, then look at tmpfile() as suggested by #Tom.
A clean, portable and non-deprecated way of creating a temporary file is provided by Boost:
auto temporary_file = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path();
Well, assuming you have been successful in creating the temporary file, you can use the remove function to delete it.
The function is declared in stdio.h -
#include <stdio.h>
int remove(const char *pathname);
For example, if you want to delete a file named myfile.txt the code will be
#include<stdio.h>
int main()
{
if(remove("myfile.txt") == -1)
{
fprintf(stderr,"Remove failed");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
I hope by now, you already know how to create the temp file, so this should resolve your query.
Hope it helps.