Строка не печатается без символа новой строки в C ++ - PullRequest
2 голосов
/ 16 ноября 2010

Я открываю файл и получаю из него строки.В первой строке должно быть указано количество переменных и их имена.Вторая строка должна быть логическим уравнением, использующим эти переменные.Задача состоит в том, чтобы распечатать таблицу истинности для переменных и уравнения.

Первая строка, которую принимает программа, не печатается, пока я не вставлю символ новой строки.Я попытался преобразовать строку и использовать printf и cout.

Основной файл, который вводит все:

#include "truthTable2.h"

int main(int argc, const char* argv[]){
  ifstream inFile;
  if(argc != 2){
    cout << "Enter an input file name: ";
    char *inFileName = "";
    cin >> inFileName;
    inFile.open(inFileName);
  }
  else
    inFile.open(argv[1]);
  TruthTable tTable;
  while(!inFile.eof()){
    char variableLine[256];
    inFile.getline(variableLine, 256);
    printf("%s ", variableLine);
    string variable(variableLine);
    tTable.setVariables(variable);
    char formulaLine[256];
    inFile.getline(formulaLine, 256);
    cout << formulaLine << "\n";
    string formula(formulaLine);
    tTable.setFormula(formula);
    tTable.printTable();
  }
  inFile.close();
  return 0;
}

Пример ввода:

2 x y
( \wedge x ( \not y ) )

Вывод из этого:

 ( \wedge x ( \not y ) )

Я думаю, что бы это ни вызывало, это доставляет мне проблемы и в остальной части программы.После токенизации variableLine он не печатает без символа новой строки и не находит вторую переменную при вычислении формулы.

Ответы [ 2 ]

5 голосов
/ 16 ноября 2010

Выход std::ostream должен быть очищен. Обычно он сбрасывается автоматически при написании перевода строки \n. Если вы хотите принудительно сбросить поток, вы можете использовать манипулятор std::flush следующим образом:

std::cout << "foo" << std::flush;

Редактировать : Хотя мой пост однозначно отвечает на вопрос "Почему моя строка не отображается, если я не вывел символ \n?" Вы сказали, что это не отвечает на ваш вопрос, поэтому я попытаюсь прочитать ум , чтобы попытаться ответить на ваш настоящий вопрос.

Поскольку у меня нет понятия , что вы действительно хотите знать, я укажу здесь несколько вещей, которые не соответствуют вашему коду, и это может помочь вам найти вашу проблему или уточнить ваш вопрос.

Во-первых, если вы используете ввод имени файла из std::cin, когда argc<2, вы гарантированно на 100% вызовете сбой в вашем приложении. Причина в том, что буфер символов, на который указывает inFileName, содержит один байт, зарезервированный для завершающего нулевого символа. Если кто-то введет любой текст вообще , вы получите переполнение буфера. Если кто-то введет пустую строку, ваша программа не откроет файл и inFile.open(...); вернет код ошибки, который вы не проверяли, поэтому ваша программа не будет аварийно завершать работу, но все равно не будет работать.

Во-вторых, входные данные других строк излишне ограничены 256 символами и столь же опасны (то есть строки длиннее 256 символов вызовут переполнение буфера). Поскольку в конечном итоге вы создаете std::string экземпляров из содержимого, вам просто следует использовать std::getline(). Он короче, более общий и безопасный.

В-третьих, описание вашей проблемы состоит в том, что вывод не генерируется, если вы не добавите символ \n. Как я уже объяснил, это совершенно нормально. Перечитав ваш пост, я могу понять, что вы не понимаете, почему вы должны добавить один, если он уже был во входном файле. Причина, по которой вам нужно добавить его, заключается в том, что функции getline() отбрасывают символ \n. Он не вставляется в буфер вашей строки.

Я убрал часть вашего кода, чтобы показать вам некоторые явные улучшения. Из этого кода вы сможете понять структуру вашей программы, которая также должна отражать структуру вашего ввода.

#include "truthTable2.h"

int main(int argc, const char* argv[]){
  std::ifstream inFile;
  if(argc != 2){
    cout << "Enter an input file name: ";
    std::string inFileName;
    std::getline(std::cin, inFileName);
    inFile.open(inFileName.c_str());
  }
  else {
    inFile.open(argv[1]);
  }
  if ( !inFile.is_open() ) {
      // Did not successfully open a file. Print error message and exit!
  }
  TruthTable tTable;
  for (std::string variables; std::getline(inFile,variables); )
  {
    std::cout << variables << std::endl;
    tTable.setVariables(variable);
    std::string formula std::getline(formula);
    std::cout << formula << std::endl;
    tTable.setFormula(formula);
    tTable.printTable();
  }
  return 0;
}

Отсюда у меня вопрос: как структурирован ваш вклад? Ваш входной файл состоит только из 2 строк? Есть ли несколько наборов этих пар линий? Есть ли одна строка с переменными и несколько уравнений? Эти три случая приведут меня к реструктуризации программы одним из следующих способов:

только 2 строки :

ThruthTable table;
std::string variables, equation;
std::getline(file, variables);
std::getline(file, equation);
// ...

Несколько комплектов :

while ( !inFile.eof() )
{
    ThruthTable table;
    std::string variables, equation;
    std::getline(file, variables);
    std::getline(file, equation);
    // ...
}

Несколько уравнений :

ThruthTable table;
std::string variables;
std::getline(variables);
for ( std::string equation; std::getline(file, equation); )
{
    std::getline(file, equation);
    // ...
}
0 голосов
/ 17 ноября 2010

Если то, что я вижу, правильно, вывод из printf - это тот, который не отображается.В этом случае либо используйте

fflush(stdout);

, либо лучше, просто используйте std :: cout для этой строки, поскольку вы пишете ее на C ++ (конечно, используя технику std::flush).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...