C++: Seg Fault on exit of IF statement(C ++:IF语句退出时的Seg Fault)
问题描述
我这次将所有代码重新发布.我希望至少有一段时间不要关闭帖子.我显然不是专家,我以前从未遇到过这样的事情,但我确实认为它对其他成员有用.我尝试了评论并同意错误与破坏有关,但找不到在哪里.我在底部的评论中包含了段错误的位置.我没有 IDE,也不知道如何使用 xterm 内置的调试器,所以我很茫然!!
I am reposting this with all of the code this time. I would appreciate not closing the post for at least a little while. I am obviously no expert and I have never run into anything like this before but I do think it can be useful to other members. I tried the comments and agree the error is with destruction but can't find where. I have included the location of the seg fault in comment towards the bottom. I don't have an IDE and don't know how to use the debugger surely built into xterm so I am at a loss!!
#include <iostream>
#include <fstream>
#include <string>
#include "File.h"
using namespace std;
string promptQuit()
{
string userMode;
cout
<<
"Would you like to [q]uit? Enter any other key to continue."
<<
endl;
cin >> userMode;
cin.clear();
cin.ignore( 1000,'
' );
return userMode;
}
int main()
{
/**************************************************************************/
/* Variable Declarations and Initializations */
/**************************************************************************/
char fileName[256];
char destinationFile[256];
string userMode;
/**************************************************************************/
/* Begin prompting user for what they want to do, starting with */
/* the filename, then what they want to do with the file. Once the user */
/* finishes with a particular file, they may continue with another file. */
/* Therefore, this loop terminates only when the user asks to quit */
/**************************************************************************/
while( userMode != "q" )
{
cout
<<
"Welcome to the file handling system. Please type the name of the "
"file that you wish to read from, write to, or modify followed by "
"the <return> key:"
<<
endl;
cin.getline( fileName, 256 );
File thisFile( fileName );
cout
<<
"Current File: " << thisFile.getFileName() << "
What would you "
"like to do?
[r]ead, [w]rite, [m]odify, or [q]uit"
<<
endl;
cin >> userMode;
// Invalid entry handling: Reset the failure bit and skip past the
// invalid input in the stream, then notify and re-prompt the user for
// valid input
while( !( (userMode == "w") | (userMode == "r") | (userMode == "q") |
(userMode == "m" ) ) )
{
cout
<<
"Invalid entry, please try again
What would you like to do?
"
"[r]ead, [w]rite, [m]odify, or [q]uit"
<<
endl;
cin >> userMode;
cin.clear();
cin.ignore( 1000, '
' );
}
/*********************************************************************/
/* Write Mode: The user is prompted to enter one number at a time */
/* and this number is written to the chosen file. If the user enters*/
/* an invalid number, such as a letter, the user is notified and */
/* prompted to enter a valid real number */
/*********************************************************************/
if( userMode == "w" )
thisFile.writeTo();
/*********************************************************************/
/* Read Mode: The user reads in the entire contents from the file */
/* they have chosen */
/*********************************************************************/
if( userMode == "r" )
thisFile.readFrom();
/*********************************************************************/
/* Modify Mode: The user may either leave the old file unmodified and*/
/* place the modified contents into a new file or actually modify the*/
/* original file. */
/* The user reads in one line from the file at a time and can either */
/* choose to accept this number, replace it, delete it, or accept it */
/* and insert one or more numbers after it. At any time the user may*/
/* also choose to accept the remainder of the numbers in the file */
/*********************************************************************/
if( userMode == "m" )
{
cout
<<
"Do you want to modify the original file?
[y]es/[n]o?"
<<
endl;
string modify;
cin >> modify;
while( !( ( modify == "y" ) | ( modify == "n" ) ) )
{
cout
<<
"Invalid entry, please try again
Do you want to modify "
"the original file?
[y]es/[n]o?"
<<
endl;
cin >> userMode;
cin.clear();
cin.ignore( 1000, '
' );
}
if( modify == "y" )
{
File tempFile;
thisFile.modify( &tempFile );
}
if( modify == "n" )
{
cout
<<
"Please type the name of the destination file followed by "
"the <return> key:"
<<
endl;
cin.getline( destinationFile, 256 );
File newFile( destinationFile );
thisFile.modify( &newFile );
/****************************************************************/
/****Seg fault occurs here. Never exits this IF but above*******/
/*function does return.Doesn't get past close curly brace********/
/****************************************************************/
}
}
userMode = promptQuit();
}
return 0;
}
这是 .cpp 文件
#include <fstream>
#include <iostream>
#include <sstream>
#include <stdlib.h>
#include <string>
#include <math.h>
#include <iomanip>
#include "File.h"
using namespace std;
// Returns ordinal number from input integer num, e.g., 1st for 1
string ordinalString( const int num )
{
stringstream numeric;
numeric << num;
string ordinalUnit;
string ordinal = numeric.str();
switch( num%10 )
{
case 1: ordinalUnit = "st"; break;
case 2: ordinalUnit = "nd"; break;
case 3: ordinalUnit = "rd"; break;
default: ordinalUnit = "th"; break;
}
switch( num )
{
case 11: ordinalUnit = "th"; break;
case 12: ordinalUnit = "th"; break;
case 13: ordinalUnit = "th"; break;
}
ordinal += ordinalUnit;
return ordinal;
}
float promptRealNumber()
{
float validEntry;
// Invalid entry handling: Reset the failure bit and skip past the
// invalid input in the stream, then notify and re-prompt the user for
// valid input
while ( !(cin >> validEntry) )
{
cout << "Invalid Input: Entry must be a real number. Please try again:";
cin.clear();
cin.ignore( 1000, '
' );
}
return validEntry;
}
File::File()
{
fileName = "temp.txt";
entries = 0;
}
File::File( const char * file_name )
{
entries = 0;
string currentLine;
fileName = file_name;
ifstream thisFile( file_name );
if ( thisFile.is_open() )
{
while ( !thisFile.eof() )
{
getline ( thisFile, currentLine );
entries++;
}
thisFile.close();
}
else
cout << "Error opening file. File may not exist." << endl;
entries--;
}
File::File( const File * copyFile )
{
fileName = copyFile->fileName;
entries = copyFile->entries;
}
void File::promptNumEntries()
{
cout
<<
"Please enter the number of entries you wish to input into "
<< fileName << " followed by the '<return>' key"
<<
endl;
// Invalid entry handling: Reset the failure bit and skip past the invalid
// input in the stream, then notify and re-prompt the user for valid input
while ( !(cin >> entries) || ( floor( entries ) != entries ) )
{
cout << "Invalid Input: Entry must be an integer. Please try again: ";
cin.clear();
cin.ignore ( 1000, '
' );
}
}
void File::readFrom()
{
string currentLine;
ifstream inFile( fileName.c_str() );
if ( inFile.is_open() )
{
while ( inFile.good() )
{
getline ( inFile, currentLine );
cout << currentLine << endl;
}
inFile.close();
}
else
cout << "Error opening file. File may not exist." << endl;
}
void File::writeTo()
{
ofstream outFile( fileName.c_str() );
string ending;
promptNumEntries();
for( int entry = 1; entry <= entries; entry++ )
{
// Notify the user which entry they are currently entering so if they lose
// their place, they can easily find which number they should be entering.
cout
<<
"Please enter the " << ordinalString( entry ) << " number followed "
"by the <return> key"
<<
endl;
float entryNum = promptRealNumber();
outFile << fixed << setprecision(1) << entryNum << endl;
}
outFile.close();
}
void File::modify( const File * destination_file )
{
ifstream sourceFile( fileName.c_str() );
ofstream destinationFile( destination_file->fileName.c_str() );
string currentLine;
string entryAction;
string insertMore = "y";
float replacementEntry;
float insertEntry;
int entry = 0;
if ( sourceFile.is_open() )
{
while ( !sourceFile.eof() )
{
getline( sourceFile, currentLine );
cout
<<
currentLine << endl << "Do you want to [k]eep this entry, "
"[r]eplace it, [d]elete it, [i]nsert after it, or accept this "
"and [a]ll remaining entries?"
<<
endl;
cin >> entryAction;
// Keep current entry. Also called when inserting an entry since
// this also requires keeping the current entry
if( ( entryAction == "k" ) | ( entryAction == "i" ) )
destinationFile << currentLine << endl;
// Replace current entry
if( entryAction == "r" )
{
cout
<<
"Please type the new entry followed by the <return> key:"
<<
endl;
replacementEntry = promptRealNumber();
destinationFile
<<
fixed << setprecision(1) << replacementEntry
<<
endl;
}
// Deleting the current entry amounts to simply ignoring it and
// continuing to the next entry, if it exists
if( entryAction == "d" );
// Insert one or more entries after current entry
if( entryAction == "i" )
{
while( insertMore == "y" )
{
cout
<<
"Please type the entry to be inserted followed by the "
"<return> key:"
<<
endl;
insertEntry = promptRealNumber();
destinationFile
<<
fixed << setprecision(1) << insertEntry
<<
endl;
cout << "Insert another number?
[y]es/[n]o?" << endl;
cin >> insertMore;
while( !( (insertMore == "y") | (insertMore == "n" ) ) )
{
cout
<<
"Invalid entry, please try again
Insert another "
"number?
[y]es/[n]o?"
<<
endl;
cin >> insertMore;
cin.clear();
cin.ignore( 1000, '
' );
}
}
}
// Accept all remaining entries
if( entryAction == "a" )
{
destinationFile << currentLine << endl;
while ( entry < entries )
{
getline ( sourceFile, currentLine );
destinationFile << currentLine << endl;
entry++;
}
}
destinationFile.close();
sourceFile.close();
}
}
else
cout << "Error opening file. File may not exist." << endl;
}
void File::copyFileContents( const File * to, const File * from )
{
ifstream fromFile( to->fileName.c_str() );
ofstream toFile( from->fileName.c_str() );
string currentLine;
while( !fromFile.fail() && !toFile.fail() )
{
for( int line = 0; line < from->entries; line++ )
{
getline( fromFile, currentLine );
toFile << currentLine;
}
}
}
这是.h文件
#include <string>
using namespace std;
class File
{
public:
File();
File( const char * );
File( const File * copyFile );
~File() { delete this; }
string getFileName() { return fileName; }
float numEntries() { return entries; }
void setNumEntries( const float numEntries ) { entries = numEntries; }
void promptNumEntries();
void readFrom();
void writeTo();
void modify( const File * );
void copyFileContents( const File * , const File * );
private:
string fileName;
float entries;
};
我尝试注释掉 sourceFile.close() 语句,但仍然没有.我知道它有很多代码,但谁能提供帮助将是我的世纪英雄!!
I tried commenting out the sourceFile.close() statement and still nothing. I know its a lot of code but whoever can help would be my hero of the century!!
推荐答案
从析构函数中移除 delete(this)
!
您没有使用 new
构造 File
(因为您在堆栈上使用静态实例),但无论如何都会调用析构函数.所以 delete
语句是无效的,可能会导致段错误.
You aren't constructing a File
with new
(since you're using a static instance on the stack), but the destructor is called anyway. So the delete
statement is invalid and probably causes the segfault.
这篇关于C ++:IF语句退出时的Seg Fault的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:C ++:IF语句退出时的Seg Fault
基础教程推荐
- 为 C/C++ 中的项目的 makefile 生成依赖项 2022-01-01
- 如何在不破坏 vtbl 的情况下做相当于 memset(this, ...) 的操作? 2022-01-01
- 管理共享内存应该分配多少内存?(助推) 2022-12-07
- 使用从字符串中提取的参数调用函数 2022-01-01
- 如何使图像调整大小以在 Qt 中缩放? 2021-01-01
- 为什么语句不能出现在命名空间范围内? 2021-01-01
- Windows Media Foundation 录制音频 2021-01-01
- 如何“在 Finder 中显示"或“在资源管理器中显 2021-01-01
- 从 std::cin 读取密码 2021-01-01
- 在 C++ 中循环遍历所有 Lua 全局变量 2021-01-01