остановить getline от удаления символа новой строки - PullRequest
2 голосов
/ 22 марта 2012

если у меня есть такой текстовый файл:

this is line one
This is line two
this is line three

Как бы я использовал getline, чтобы прочитать каждый из них в потоке строки, а затем распечатать поток в новую строку, сохранив при этом символ новой строки? Я на Mac с использованием Xcode 4. Вот мой код: у меня проблемы, потому что текст, который он печатает, печатает только в одной строке.

#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 ]

3 голосов
/ 10 января 2018

Я знаю, что это старый вопрос, но я думаю, что могу немного улучшить ответ @ Бенджамин Линдли выше.Форсирование новой строки в конце каждого вызова 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;
    }
}

Обновление: похоже, что приведенный выше код работал из-за ошибки в стандартной библиотеке, которую я использовал.В соответствии с спецификацией std :: getline ...

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

Пример работающего в режиме онлайн

2 голосов
/ 22 марта 2012
getline( the_stream, the_string );
the_string += '\n';
...