如果我有这样的文本文件:
this is line one
This is line two
this is line three
如何使用getline将每个读取到字符串流中,然后将流打印到新字符串中,同时保留换行符?我在使用Xcode 4的Mac上。这是我的代码:我遇到了麻烦,因为它打印的文本只打印在一行上。
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <sstream>
#include <cctype>
using namespace std;
string getInput ();
ifstream * openInFile ();
int getShiftValue ();
void cypherMenu ();
void menu ();
string shiftCharacters (int shiftNum, ifstream * inFile);
string getOutput ();
ofstream * openOutFile ();
void printSentence (string outData, ofstream * outFile);
void notOption (string optionString);
string capitalize (string choice);
string option ();
int main() {
ifstream * inFile;
ofstream * outFile;
string inFileName, outFileName, outData, optionString, capOptionString;
int shiftNum = 0;
bool isOption = false;
while (capOptionString.compare("2") != 0 ||
capOptionString.compare("QUIT") != 0) {
do {
menu();
optionString = option();
capOptionString = capitalize(optionString);
if (capOptionString.compare("1") == 0 || capOptionString.compare("CAESAR")
== 0) {
isOption = true;
}
else if (capOptionString.compare("2") == 0 ||
capOptionString.compare("QUIT") == 0) {
isOption = false;
return 0;
}
else {
notOption(optionString);
}
}
while (!isOption);
cypherMenu();
inFile = openInFile();
shiftNum = getShiftValue();
outData = shiftCharacters(shiftNum, inFile);
inFile->clear();
inFile->close();
outFile = openOutFile();
printSentence(outData, outFile);
outFile->clear();
outFile->close();
}
return 0;
}
// Input Functions
string getInput () {
cout << "Enter an input file name: ";
string inFileName;
getline(cin, inFileName);
return inFileName;
}
string getOutput () {
string outFileName;
cout << "Enter an output file name: ";
getline(cin, outFileName);
cout << endl;
return outFileName;
}
ifstream * openInFile () {
ifstream * inFile;
bool isGood = false;
string inFileName;
inFile = new ifstream;
do {
inFileName = getInput();
inFile->open(inFileName.c_str());
if (inFile->fail()) {
cout << "Couldn't open file" << endl;
}
else {
isGood = true;
}
}
while (!isGood);
return inFile;
}
ofstream * openOutFile () {
ifstream testStream;
ofstream * outFile;
bool isUnique = false;
string fileName;
do {
fileName = getOutput();
testStream.clear();
testStream.open(fileName.c_str(), ios_base::in);
if (testStream.good()) {
cout << "The file already exists, please choose another"
<< endl;
testStream.clear();
testStream.close();
}
else {
isUnique = true;
testStream.clear();
testStream.close();
}
}
while (!isUnique);
outFile = new ofstream;
outFile->open(fileName.c_str());
return outFile;
}
int getShiftValue () {
int shiftNum;
string trash;
cout << "Please enter shift value: ";
cin >> shiftNum;
getline(cin, trash);
return shiftNum;
}
string option () {
string optionString;
getline(cin, optionString);
cout << endl;
return optionString;
}
// Data manipulation functions
**string shiftCharacters (int shiftNum, ifstream * inFile){
string inData, outData, trash;
char outChar;
int idx = 0, length = 0;
stringstream outSentence;
do {
while (getline(* inFile, inData, '\n')) {
getline(* inFile, trash);
for (idx = 0; idx <= inData.length() - 1; idx++) {
if (inData[idx] >= 'a' && inData[idx] <= 'z') {
outChar = (((inData[idx] - 'a') + shiftNum) % 26) +
'a';
outSentence << outChar;
length += 1;
}
else if (inData[idx] >= 'A' && inData[idx] <= 'Z') {
outChar = (((inData[idx] - 'A') + shiftNum) % 26) +
'A';
outSentence << outChar;
length += 1;
}
else {
outChar = inData[idx];
outSentence << outChar;
length += 1;
}
}
outSentence << trash;
}
}
while (!(inFile->eof()));
outData.resize(length);
while (!(outSentence).eof()) {
// outSentence >> noskipws >> outData;
getline(outSentence, outData);
}
return outData;
}**
string capitalize (string choice) {
string outString;
outString.resize(choice.length());
transform(choice.begin(), choice.end(), outString.begin(), ::toupper);
return outString;
}
// Output funcitons
void cypherMenu () {
cout << "C A E S A R C Y P H E R P R O G R A M" << endl
<< "========================================" << endl;
return;
}
void printSentence (string outData, ofstream * outFile) {
int idx = 0;
char outChar;
stringstream outString;
outString << outData;
for (idx = 0; idx <= outData.length() - 1; idx++) {
outChar = outString.get();
outFile->put(outChar);
}
}
void menu () {
cout << "Available Options: " << endl
<< "1. CAESAR - encrypt a file using Caesar Cypher" << endl
<< "2. QUIT - exit the program" << endl << endl
<< "Enter a keyword or option index: ";
return;
}
void notOption (string optionString) {
cout << optionString << " is an unrecognized option, try again" << endl
<< endl;
return;
}
问题在于shiftCharacters函数。我不知道如何保持新行字符请帮忙?代码是可编译的。
答案 0 :(得分:3)
我知道这是一个老问题,但我认为我可以在@Benjamin Lindley上面的答案中略微提高一点。在getline()
的每次调用结束时强制换行,如@David L.所述,“可能无法反映最后一行的实际输入。”
相反,您可以在阅读该行后调用std::istream::peek()
以查看是否有更多字符。如果peek()
未返回EOF
,则可以安全地添加新行 。以下示例代码......
std::string s;
while (std::getline(std::cin, s)) {
std::cout << s;
if (std::cin.peek() != EOF) {
std::cout << std::endl;
}
}
更新:由于我使用的标准库中存在错误,上面的代码看起来很有效。根据{{3}} ...
1) ...
2) ...
b) the next available input character is delim, as tested by
Traits::eq(c, delim), in which case the delimiter character
is extracted from input, but is not appended to str.
因此,在符合标准的库上,代码应如下所示。
std::string s;
while (std::getline(std::cin, s)) {
std::cout << s;
if (std::cin.good()) {
std::cout << std::endl;
}
}
答案 1 :(得分:2)
getline( the_stream, the_string );
the_string += '\n';