0

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. I face with logical error during Runtime; whatever I as user write doesn't type into the output terminal and it doesn't succeed more steps. Apparently fwrite function with this feature in the libraries exists, but I want to write my own code differently this way. I think I must have neglected a point. Here's the code:

#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();
}
Armin
  • 135
  • 7
  • `istream& getline (istream& is, string& str);` is it proper C++ to put a function declaration inside that scope area...? – TrebledJ Aug 19 '18 at 08:29
  • dear @JohnLaw, I'm not completely sure whether it is proper to put the getline function's declaration inside that scope area or not. – Armin Aug 19 '18 at 08:32
  • Well, I'm no expert myself, but I've never seen anything like it. If you're using `getline`, directly pass the `istream` and `std::string` to receive input (e.g. `getline(std::cin, strBuff);`. Then maybe write strBuff into the qTextStream. – TrebledJ Aug 19 '18 at 08:34
  • dear @JohnLaw, It gets "cin is not member of std" error. and I have already tried to write the strBuff (or my "str" buffer variable) into the QTextStream inside the wFile function code. – Armin Aug 19 '18 at 08:57
  • ... `std::cin` comes along with the `iostream` header file... you can guess my next question... – TrebledJ Aug 19 '18 at 08:58
  • dear @JohnLaw, yes you're right I've neglected iostream, but I still have syntax error of: no matching function for call to 'getline(std::istream&, QTextStream&)' getline(std::cin, str); – Armin Aug 19 '18 at 09:02
  • 1
    there's no overload for `getline(std::istream&, QTextStream&)`. Please check the [documentation](https://en.cppreference.com/w/cpp/string/basic_string/getline) and at least do some preliminary research on how to use it ([SO thread on how to use std::getline](https://stackoverflow.com/questions/18786575/using-getline-in-c)). – TrebledJ Aug 19 '18 at 09:06

1 Answers1

2

Spoiler alarm: At the very end of this answer, there is a very simple recommendation for a fix.

What OP did

Concerning istream& getline (istream& is, string& str); in wFile(QString Filename):

This declares function getline() in function wFile().

  1. This is a valid declaration concerning C++.

  2. Concerning the sample code, I missed the respective headers. IMHO,
    #include <istream> and
    #include <string>
    are required to make this compiling.
    However, it is possible that the existing #includes include them indirectly. So, OP's code may even compile without them.

  3. Declaring functions, which are not used as well as re-declaring functions which are already declared is somehow useless but not wrong.

To demonstrate this, I made a small sample:

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

compiles and runs perfectly.

Output:

in func()

Live Demo on coliru

What OP (probably) wanted

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.

This sounds a bit confusing to me. std::getline(std::cin, ) can be used to read user input from console. May be, it's a bit bad wording only.

Assuming, the OP wanted to read input from console, obviously, declaring a function is not sufficient – it must be called to become effective:

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

Output:

Enter file name: test.txt
Got file name 'test.txt'

Live Demo on coliru

C++ std vs. Qt

Qt is undoubtly built on top of the C++ std library. However, though it's possible it is not recommended to mix both APIs when it can be prevented (or there aren't specific reasons to do so).

Both, Qt and C++ std, are a possibility to write portable software. Qt covers a lot of things which are provided in the std library as well but a lot of other things additionally which are not or not yet part of std. In some cases, the Qt is a bit less generic but more convenient though this is my personal opinion. IMHO, the following explains how I came to this:

std::string vs. QString

std::string stores a sequence of chars. The meaning of chars when exposed as glyph (e.g. printing on console or displaying in a window) depends on the encoding which is used in this exposing. There are lot of encodings which interprete the numbers in the chars in distinct ways.

Example:

std::string text = "\xc3\xbc";

Decoded/displayed with

Based on character type of std::string, it is not possible to determine the encoding. Hence, an additional hint must be provided to decode this properly.

(AFAIK, it is similar for std::wstring and wchar_t.)

QString stores a sequence of Unicode characters. So, one universal encoding was chosen by design to mitigate the "encoding hell".

As long as the program operates on QString, no encoding issues should be expected. The same is true when combining QString with other functions of Qt. However, it becomes a bit more complicated when "leaving the Qt universe" – e.g. storing contents of a std::string to QString.

This is the point where the programmer has to provide the additional hint for the encoding of the contents in std::string. QString provides a lot of from...() and to...() methods which can be used to re-encode contents but the application programmer is still responsible to chose the right one.

Assuming that the intended contents of text should have been the ü (i.e. UTF-8 encoding), this can be converted to QString (and back) by:

// 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();

This has to be considered when input from std::cin shall be passed to QString:

std::cout << "Enter file name: ";
std::string input; std::getline(std::cin, input);
QString qFileName = QString::fromLocal8Bit(input);

And even now, the code contains a little flaw – the locale of std::cin might have changed with std::ios::imbue(). I must admit that I cannot say much more about this. (In daily work, I try to prevent this topic at all e.g. by not relying on Console input which I consider especially critical on Windows – the OS on which we usually deploy to customers.)

Instead, a last note about OP's code:

How to fix it

Remembering my above recommendation (not to mix std and Qt if not necessary), this can be done in Qt exclusively:

QTextStream qtin(stdin);
qtin.readline();

I must admit that I never did it by myself but found this in the Qt forum: Re: stdin reading.

Scheff's Cat
  • 19,528
  • 6
  • 28
  • 56
  • dear @Scheff! what a comprehensive perfect answer! thanks a lot. I understood my mistake, I just were mixing Qt liberaries with std. I mark it as answered perfectly:) – Armin Aug 19 '18 at 12:57