最良のオプションは、一時ファイルを作成することであり、これが出力ファイルになるはずです。なぜそうすべきかを説明するには、質問の下のコメントを読んでください。
そして、これはうまく機能する良いクリーンな例です。
#include <string>
#include <iostream>
#include <fstream>
#include <sys/stat.h>
/*
* @ FUNCTION: GenerateStr
* @ PARAMETER(s):
* [1st - in] const size_t in_Length = This parameter
* take in a size_t, which should be the length of the
* generated std::string.
* @ RETURN VALUE(s):
* This function should return the generated
* std::string, which was randomized during
* the generating process within this function.
*/
std::string GenerateStr( const size_t in_Length ) {
const std::string Elements =
"AaBcCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz1234567890$-_";
std::string FileName = "";
for( size_t Index = 0; Index != in_Length; ++ Index ) {
//# Add random characters from Elements.
FileName += Elements[ rand() % Elements.size() ];
}
return FileName;
};
/*
* @ FUNCTION: FileExists
* @ PARAMETER(s):
* [1st - in] const std::string &in_File = This parameter
* takes in a std::string, which should be the
* name of the file that will be searched for.
* @ RETURN VALUE(s):
* false = The file does not exists.
* true = The file does exists.
*/
bool FileExists( const std::string &in_FileName ) {
struct stat Buffer;
return ( stat( in_FileName.c_str(), &Buffer ) != -1 );
};
/*
* @ FUNCTION: GenerateTempFileName
* @ PARAMETER(s):
* [1st - in] const size_t in_Length = This parameter
* takes in a constant size_t value, which should be
* length of temporary file name (a.k.a the returned
* value).
* @ RETURN VALUE(s):
* This function will return a std::string, which
* should be a unique name for the temporary file.
*/
std::string GenerateTempFileName( const size_t in_Length ) {
std::string TempFileName = "";
while( FileExists( TempFileName = GenerateStr( in_Length ) + ".tmp" ) );
return TempFileName;
};
/*
* @ FUNCTION: OldFileToTempFile
* @ PARAMETER(s):
* [1st - in] const std::string &in_OldFileName = The
* name of the old file.
* [2nd - in] const std::string &in_TempFileName = The
* name of the temporary file.
* @ RETURN VALUE(s):
* 1 = An error has occured when attempting to rename the
* the old file to a temporary name.
* -1 = An error has occured when attempting to rename the
* temporary file to the original name of the old file,
* which is in_OldFileName.
* -2 = This is only a warning, although this function
* successfully renamed the temporary file to the original
* name of the old file, it failed to delete the old file.
* 0 = Successfully renamed the temporary file to
* in_OldFileName and deleted the old file.
*/
short OldFileToTempFile( const std::string &in_OldFileName,
const std::string &in_TempFileName )
{
//# Generate a temporary name for the old file.
const std::string OldFileTmpName = GenerateTempFileName( 15 );
//# Rename the old file to a temporary name. Why? So we can rename
// it back to its original name incase it failed to rename the
// temporary file.
if( std::rename( in_OldFileName.c_str(), OldFileTmpName.c_str() ) != 0 ) {
return 1;
}
//# If we successfully renamed the old file to a temporary name,
// we shall then attempt to rename the temporary file to the original
// name of the old file.
//# Attempt to rename the temporary file. If we fail, we shall rename
// the old file back to its original name.
if( std::rename( in_TempFileName.c_str(), in_OldFileName.c_str() ) != 0 ) {
std::rename( OldFileTmpName.c_str(), in_OldFileName.c_str() );
return -1;
}
//# Now if we successfully renamed the temporary file,
// we can go ahead and delete the old file. If failed,
// we shall return -2, which should only be a warning
// that we failed to delete the old file.
if( std::remove( OldFileTmpName.c_str() ) != 0 ) {
return -2;
}
return 0;
};
//# I wrote this function so it can instruct function ProcessFile to either skip
// the current line (in_Line) or to output the line to the temporary file. But
// mainly because, I did not know what your function processLine was actually
// doing.
bool ProcessLine( std::string &in_Line ) {
//# If in_Line is equal to "SkipThisLine", we shall return true,
// which means to skip the line. Else, it will return false,
// which simply means to no skip the line.
return ( in_Line == "SkipThisLine" );
};
/*
* @ FUNCTION: Example
* @ DESCRIPTION:
* This function is an example of how to read and write a file and also
* to answer the question above.
*/
bool Example() {
//# Attempt to open InFile (Test.txt).
std::ifstream InFile( "Test.txt" );
//# Return false if we are unable to open InFile.
if( ! InFile.is_open() ) {
std::cerr << "\nUnable to open file: Test.txt\n";
return false;
}
//# Generate a unqiue name for the temporary file.
const std::string TempFileName = GenerateTempFileName( 15 );
//# Create temporary file.
std::ofstream TempFile( TempFileName );
std::string InLine = "";
//# Begin processing each lines within InFile.
while( std::getline( InFile, InLine ) ) {
//# Process the line and check if we are suppose to skip it or not.
if( ! ProcessLine( InLine ) ) {
//# If we do not skip the line, we shall then write it to the
// temporary file (TempFile).
TempFile << InLine << std::endl;
}
}
//# Now that we are done with InFile, we can
// close both InFile and TempFile and continue
// to the next set of steps.
InFile.close();
TempFile.close();
//# Attempt to rename the temporary file to Test.txt.
short Error = OldFileToTempFile( "Test.txt", TempFileName );
//# Check if there are no error or if the error is -2.
// The -2 means that we successfully renamed the temporary
// file but we were unable to delete the old file.
if( Error == 0 || Error == -2 ) {
return true;
}
//# Failed to rename temporary file.
return false;
};
int main() {
if( Example() ) {
std::cout << "Success!" << std::endl;
} else { std::cout << "Failed!" << std::endl; }
::getchar();
return 0;
};
コメントを読んでください、彼らは本当に役に立ちます!:)
以下の@Michael Andersonのコメントにより、いくつかの重要な変更を加えました。彼に感謝します。