停止getline丢弃换行符

时间:2012-03-22 02:17:06

标签: c++ newline getline

如果我有这样的文本文件:

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函数。我不知道如何保持新行字符请帮忙?代码是可编译的。

2 个答案:

答案 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;
    }
}

the std::getline spec

答案 1 :(得分:2)

getline( the_stream, the_string );
the_string += '\n';