【问题标题】:String is not printing without new line character in C++字符串在 C++ 中没有换行符就不会打印
【发布时间】:2011-05-11 01:34:10
【问题描述】:

我正在打开一个文件,并从中获取行。 第一行应该说明有多少变量,以及它们的名称。 第二行应该是使用这些变量的逻辑方程。 任务是让它打印出变量和方程的真值表。

如果没有我插入一个换行符,程序接收的第一行就不会打印。我尝试转换为字符串并同时使用 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 进行标记后,它不会在没有换行符的情况下打印,并且在评估公式时找不到第二个变量。

【问题讨论】:

  • printf 和 cout 一起发现
  • while(!inFile.eof()){
  • 尝试读心。重新阅读我的答案。

标签: c++ char printf ifstream cout


【解决方案1】:

std::ostream 的输出需要刷新。它通常在写入换行符\n 时自动刷新。如果你想强制流刷新,你可以像这样使用std::flush 操纵器:

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

编辑:虽然我的帖子清楚地回答了“为什么我的行不显示,除非我输出 \n 字符?”的问题?你说这并不能回答你的问题,所以我会尝试一些读心术来尝试回答你真正的问题。

由于我不知道您真正想知道什么,我将在此指出您的代码中存在的几处错误,它可能会帮助您找到问题或澄清您的问题。

首先,如果您使用从std::cin 输入的文件名,当argc&lt;2 时,您将100% 保证会导致您的应用程序失败。原因是inFileName 指向的字符缓冲区包含一个字节,为终止空字符保留。如果有人输入 any 文本 whatsoever,您将得到缓冲区溢出。如果有人输入一个空字符串,您的程序将不会打开任何文件,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);
    // ...
}

【讨论】:

  • @Chubsdad:是的。上次我检查微软的实现时,它只是将\n 插入到流中,自动刷新它。
  • 这并没有解决问题。我获取输入文件的方法有什么问题吗?我觉得第一行的结尾有问题,它把其他一切都搞砸了。
  • 对不起,不清楚,感谢您的描述性回答。我认为之前的问题是,在输入第一行时,在末尾添加了垃圾,这使得它无法打印,并且在我比较变量向量中的最后一个元素时给它带来了问题。我将程序更改为全部在一个文件中(不好的编程习惯),并通过对所有输入使用 inFile >> tempString 使其工作。感谢您的帮助。
  • 请注意inFile &gt;&gt; tempString 一次只能读取一个令牌。要阅读整行,您应该使用getline(inFile, tempString)
  • 是的,我知道这一点,我试图隐瞒细节,因为我现在一切都已经解决了,不想用不必要的细节来打扰你。
【解决方案2】:

如果我看到的是正确的,那么 printf 的输出就是没有显示的输出。在这种情况下,要么使用

fflush(stdout);

或者更好,因为你是用 C++ 编写的,所以只需为该行添加一个 std::cout (当然使用std::flush 技术。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-19
    相关资源
    最近更新 更多