通过getline函数从终端获取用户输入并将其写入文件时出现Qt逻辑错误
Qt logical error during getting user's input from terminal via getline function and writing it into a file
使用控制台,我想通过 wFile 中的 getline 函数将所需用户的输入写入文件 函数,然后读取它。我在运行时遇到逻辑错误;无论我作为用户写什么,都不会输入输出终端,也不会成功执行更多步骤。显然,库中存在具有此功能的 fwrite 函数,但我想以这种方式编写自己的代码。我想我一定是忽略了一点。这是代码:
#include <QCoreApplication>
#include <QDebug>
#include <QFile>
#include <QString>
#include <QTextStream>
#include <String>
#include <cstdlib>
using namespace std;
void wFile(QString Filename)
{
QFile mFile(Filename);
QTextStream str(&mFile);
qDebug() << "what do you want to write in the desired file: ";
istream& getline (istream& is, string& str);
if (!mFile.open(QFile::WriteOnly | QFile::Text))
{
qDebug() << "could not open the file";
return;
}
mFile.flush();
mFile.close();
}
void read (QString Filename){
QFile nFile(Filename);
if(!nFile.open(QFile::ReadOnly | QFile::Text))
{
qDebug() << "could not open file for reading";
return;
}
QTextStream in(&nFile);
QString nText = in.readAll();
qDebug() << nText;
nFile.close();
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QString nFilename ="P:/DocumentArminV.txt";
wFile(nFilename);
read(nFilename);
return a.exec();
}
剧透警报:在这个答案的最后,有一个非常简单的修复建议。
OP 做了什么
关于 wFile(QString Filename)
中的 istream& getline (istream& is, string& str);
:
这在函数 wFile()
中声明了函数 getline()
。
这是关于 C++ 的有效声明。
关于示例代码,我错过了相应的headers。恕我直言,
#include <istream>
和
#include <string>
需要进行此编译。
但是,现有的 #include
有可能间接包含它们。因此,OP 的代码甚至可以在没有它们的情况下编译。
声明未使用的函数以及 re-declaring 已经声明的函数在某种程度上是无用的,但没有错。
为了证明这一点,我制作了一个小样本:
#include <cstdio>
#include <istream>
#include <string>
void func()
{
puts("in func()\n");
std::istream& getline(std::istream&, std::string&);
// Even duplicated prototyping is accepted without complaints:
std::istream& getline(std::istream&, std::string&);
}
int main ()
{
func();
return 0;
}
完美编译和运行。
输出:
in func()
OP(可能)想要什么
Using console, I want to write the desired user's input into a file via getline function inside the wFile function and then read it.
这听起来让我有点困惑。 std::getline(std::cin, )
可用于从控制台读取 用户输入。可能是,只是措辞有点不好。
假设,OP 想要从控制台读取输入,显然,声明一个函数是不够的——必须调用它才能生效:
#include <iostream>
void func()
{
std::cout << "Enter file name: ";
std::string fileName; std::getline(std::cin, fileName);
std::cout << "Got file name '" << fileName << "'\n");
}
int main ()
{
func();
return 0;
}
输出:
输入文件名:test.txt<kbd>↵</kbd>
得到文件名 'test.txt'
C++ std
与 Qt
Qt 无疑是建立在 C++ std
库之上的。但是,尽管可以避免混合使用这两种 API(或者没有特定原因),但不建议混合使用。
Qt 和 C++ std
都可以编写可移植软件。
Qt 涵盖了 std 库中提供的很多东西,但还有很多其他东西没有或还不是 std
的一部分。在某些情况下,Qt 不太通用但更方便,尽管这是我个人的看法。恕我直言,以下解释了我是如何得出这个结论的:
std::string
对比 QString
std::string
存储 char
的序列。 char
作为字形公开时的含义(例如在控制台上打印或在 window 中显示)取决于此公开中使用的编码。有很多编码以不同的方式解释 char
中的数字。
示例:
std::string text = "\xc3\xbc";
Decoded/displayed 和
- Windows-1252:
ü
- UTF-8:
ü
根据 std::string
的字符类型,无法确定编码。因此,必须提供 附加提示 才能正确解码。
(据我所知,std::wstring
和 wchar_t
类似。)
QString
stores a sequence of Unicode 个字符。因此,设计选择了一种通用编码来减轻 "encoding hell".
只要程序在 QString
上运行,就不会出现编码问题。将QString
与Qt的其他函数结合起来也是如此。然而,当 "leaving the Qt universe" 时,它会变得有点复杂——例如将 std::string
的内容存储到 QString
.
这是程序员必须为 std::string
中的内容编码提供 附加提示 的地方。 QString
提供了很多 from...()
和 to...()
方法可以用于 re-encode 内容,但应用程序程序员仍然有责任选择正确的方法。
假设 text
的预期内容应该是 ü
(即 UTF-8 编码),这可以通过以下方式转换为 QString
(并返回):
// std::string (UTF-8) -> QString
std::string text = "\xc3\xbc";
QString qText = QString::fromUtf8(text.c_str());
// QString -> std::string (UTF-8)
std::string text2 = qText.toUtf8();
将来自 std::cin
的输入传递给 QString
时必须考虑这一点:
std::cout << "Enter file name: ";
std::string input; std::getline(std::cin, input);
QString qFileName = QString::fromLocal8Bit(input);
即使是现在,代码仍然存在一点缺陷——std::cin
的语言环境可能已经随着 std::ios::imbue()
发生了变化。我必须承认,对此我不能说太多。 (在日常工作中,我试图完全避免这个话题,例如不依赖我认为对 Windows 特别重要的控制台输入 – 我们通常在其上部署给客户的 OS。)
相反,关于 OP 代码的最后一个注释:
如何修复
记住我上面的建议(如果没有必要不要混合 std 和 Qt),这可以在 Qt 中独占完成:
QTextStream qtin(stdin);
qtin.readline();
我必须承认我从来没有自己做过,但在 Qt 论坛上发现了这个:Re: stdin reading。
使用控制台,我想通过 wFile 中的 getline 函数将所需用户的输入写入文件 函数,然后读取它。我在运行时遇到逻辑错误;无论我作为用户写什么,都不会输入输出终端,也不会成功执行更多步骤。显然,库中存在具有此功能的 fwrite 函数,但我想以这种方式编写自己的代码。我想我一定是忽略了一点。这是代码:
#include <QCoreApplication>
#include <QDebug>
#include <QFile>
#include <QString>
#include <QTextStream>
#include <String>
#include <cstdlib>
using namespace std;
void wFile(QString Filename)
{
QFile mFile(Filename);
QTextStream str(&mFile);
qDebug() << "what do you want to write in the desired file: ";
istream& getline (istream& is, string& str);
if (!mFile.open(QFile::WriteOnly | QFile::Text))
{
qDebug() << "could not open the file";
return;
}
mFile.flush();
mFile.close();
}
void read (QString Filename){
QFile nFile(Filename);
if(!nFile.open(QFile::ReadOnly | QFile::Text))
{
qDebug() << "could not open file for reading";
return;
}
QTextStream in(&nFile);
QString nText = in.readAll();
qDebug() << nText;
nFile.close();
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QString nFilename ="P:/DocumentArminV.txt";
wFile(nFilename);
read(nFilename);
return a.exec();
}
剧透警报:在这个答案的最后,有一个非常简单的修复建议。
OP 做了什么
关于 wFile(QString Filename)
中的 istream& getline (istream& is, string& str);
:
这在函数 wFile()
中声明了函数 getline()
。
这是关于 C++ 的有效声明。
关于示例代码,我错过了相应的headers。恕我直言,
#include <istream>
和
#include <string>
需要进行此编译。
但是,现有的#include
有可能间接包含它们。因此,OP 的代码甚至可以在没有它们的情况下编译。声明未使用的函数以及 re-declaring 已经声明的函数在某种程度上是无用的,但没有错。
为了证明这一点,我制作了一个小样本:
#include <cstdio>
#include <istream>
#include <string>
void func()
{
puts("in func()\n");
std::istream& getline(std::istream&, std::string&);
// Even duplicated prototyping is accepted without complaints:
std::istream& getline(std::istream&, std::string&);
}
int main ()
{
func();
return 0;
}
完美编译和运行。
输出:
in func()
OP(可能)想要什么
Using console, I want to write the desired user's input into a file via getline function inside the wFile function and then read it.
这听起来让我有点困惑。 std::getline(std::cin, )
可用于从控制台读取 用户输入。可能是,只是措辞有点不好。
假设,OP 想要从控制台读取输入,显然,声明一个函数是不够的——必须调用它才能生效:
#include <iostream>
void func()
{
std::cout << "Enter file name: ";
std::string fileName; std::getline(std::cin, fileName);
std::cout << "Got file name '" << fileName << "'\n");
}
int main ()
{
func();
return 0;
}
输出:
输入文件名:test.txt<kbd>↵</kbd>
得到文件名 'test.txt'
C++ std
与 Qt
Qt 无疑是建立在 C++ std
库之上的。但是,尽管可以避免混合使用这两种 API(或者没有特定原因),但不建议混合使用。
Qt 和 C++ std
都可以编写可移植软件。
Qt 涵盖了 std 库中提供的很多东西,但还有很多其他东西没有或还不是 std
的一部分。在某些情况下,Qt 不太通用但更方便,尽管这是我个人的看法。恕我直言,以下解释了我是如何得出这个结论的:
std::string
对比 QString
std::string
存储 char
的序列。 char
作为字形公开时的含义(例如在控制台上打印或在 window 中显示)取决于此公开中使用的编码。有很多编码以不同的方式解释 char
中的数字。
示例:
std::string text = "\xc3\xbc";
Decoded/displayed 和
- Windows-1252:
ü
- UTF-8:
ü
根据 std::string
的字符类型,无法确定编码。因此,必须提供 附加提示 才能正确解码。
(据我所知,std::wstring
和 wchar_t
类似。)
QString
stores a sequence of Unicode 个字符。因此,设计选择了一种通用编码来减轻 "encoding hell".
只要程序在 QString
上运行,就不会出现编码问题。将QString
与Qt的其他函数结合起来也是如此。然而,当 "leaving the Qt universe" 时,它会变得有点复杂——例如将 std::string
的内容存储到 QString
.
这是程序员必须为 std::string
中的内容编码提供 附加提示 的地方。 QString
提供了很多 from...()
和 to...()
方法可以用于 re-encode 内容,但应用程序程序员仍然有责任选择正确的方法。
假设 text
的预期内容应该是 ü
(即 UTF-8 编码),这可以通过以下方式转换为 QString
(并返回):
// std::string (UTF-8) -> QString
std::string text = "\xc3\xbc";
QString qText = QString::fromUtf8(text.c_str());
// QString -> std::string (UTF-8)
std::string text2 = qText.toUtf8();
将来自 std::cin
的输入传递给 QString
时必须考虑这一点:
std::cout << "Enter file name: ";
std::string input; std::getline(std::cin, input);
QString qFileName = QString::fromLocal8Bit(input);
即使是现在,代码仍然存在一点缺陷——std::cin
的语言环境可能已经随着 std::ios::imbue()
发生了变化。我必须承认,对此我不能说太多。 (在日常工作中,我试图完全避免这个话题,例如不依赖我认为对 Windows 特别重要的控制台输入 – 我们通常在其上部署给客户的 OS。)
相反,关于 OP 代码的最后一个注释:
如何修复
记住我上面的建议(如果没有必要不要混合 std 和 Qt),这可以在 Qt 中独占完成:
QTextStream qtin(stdin);
qtin.readline();
我必须承认我从来没有自己做过,但在 Qt 论坛上发现了这个:Re: stdin reading。