Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Помогите найти ошибку (запись в файл)
Форум на CrossPlatform.RU > Библиотеки > Qt > Qt Ввод/Вывод, Сеть. Межпроцессное взаимодействие
++Norton++
Есть функция, которая выполняет запись в файл:
int catFile(QString param, QString nof)
{
  int i;
  QStringList content;
  QFile file(nof);

  if(param==">")
  {
    if(!file.open(QIODevice::WriteOnly | QIODevice::Text))
         return 1;
    QTextStream in(stdin);

    while(!in.atEnd())
    {
      content.append(in.readLine()+"\n");
    }
     QTextStream out(&file);
     for(i=0; i<content.count(); i++)
     {
       out << content.at(i);
     }
     file.close();
     return 0;
  }
}

Дело в том, что при ее первом вызове, все работает нормально. Если следом ее вызвать второй раз, она просто создает пустой файл (т.е. пробрасывает стадию while(!in.atEnd)). Что может быть не так?
AD
Ну насколько я понимаю, тебе следует каким-нибудь образом указать потоку ввода stdin, чтобы он переместил указатель на начало и считывал введенные данные по новой. Как именно, почитай QIODevice, QFile.
Litkevich Yuriy
Цитата(++Norton++ @ 11.10.2008, 17:17) *
while(!in.atEnd())
{
content.append(in.readLine()+"\n");
}
вот эти строчки объясни.
Tonal
И чё тут странного?
Ты в первый раз выгребаешь всё из stdin.
Во второй запуск там естественно уже ничего нет - он как встал в режим atEnd в первый раз, так там и стоит.
++Norton++
Litkevich Yuriy, эта строчка читает со стандартного ввода линию и заносит ее в QStringList.
На счет режима atEnd()... а можно как-нибудь вывести из этого режима, чтобы и при последующих запусках все работало как надо?
AD
Цитата(++Norton++ @ 11.10.2008, 23:28) *
Litkevich Yuriy, эта строчка читает со стандартного ввода линию и заносит ее в QStringList.
На счет режима atEnd()... а можно как-нибудь вывести из этого режима, чтобы и при последующих запусках все работало как надо?

Объясните корректно, пожалуйста, чего Вы хотите добиться. Неясно какой результат нужен! :))))
Litkevich Yuriy
Цитата(++Norton++ @ 12.10.2008, 2:28) *
со стандартного ввода линию и
читает строку, а сама строка чем заканчивается? <Ctrl>+<D>? т.е. это не прерывает ввод данных, а только сигналит о завершении строки?
Я так понимаю ты все это делаешь в GNU/Linux

Цитата(AD @ 12.10.2008, 2:34) *
Объясните корректно, пожалуйста, чего Вы хотите добиться. Неясно какой результат нужен! )))
Присоеденяюсь.
Лучше объясни каков должен быть результат работы модуля/программы, возможно все проще.
++Norton++
Да, все делаю в Linux.
Просто нужна функция, которая работала бы аналогично линуксовой команде (cat > file.name). Т.е. читала строку за строкой что вводит пользователь и потом записывала в файл. Если пользователь нажимает Enter, нужно просто перейти на следующую строку, но не закончить выполнение. Закончить выполнение нужно тогда, когда пользователь нажмет ctrl+D.
AD
Цитата(++Norton++ @ 11.10.2008, 23:44) *
Да, все делаю в Linux.
Просто нужна функция, которая работала бы аналогично линуксовой команде (cat > file.name). Т.е. читала строку за строкой что вводит пользователь и потом записывала в файл. Если пользователь нажимает Enter, нужно просто перейти на следующую строку, но не закончить выполнение. Закончить выполнение нужно тогда, когда пользователь нажмет ctrl+D.

Хорошо, а как она делает по тому коду, что здесь был приведен? Не работаю в Линукс, поэтому смогу помочь, когда узнаю все подробности! :))))
Litkevich Yuriy
Цитата(++Norton++ @ 12.10.2008, 2:44) *
Если пользователь нажимает Enter, нужно просто перейти на следующую строку, но не закончить выполнение. Закончить выполнение нужно тогда, когда пользователь нажмет ctrl+D.
А разве ввод не прекращается при нажатии <Enter>?
++Norton++
В том то и дело, что просто переходит на другую линию (так, в принципе, и надо).
Litkevich Yuriy
ну я кажется просто торможу, вот такой код попробуй:
#include <QtCore>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QFile        file("./outfile.txt");
    QTextStream    out(&file);
    QTextStream    in(stdin);
    QString        cmdline;

    /*qDebug() << */file.open(QIODevice::WriteOnly/* | QIODevice::Text*/);

    while (!in.atEnd())
    {
        cmdline=in.readLine();
        out << cmdline;
    }
    file.close();

    return 0;
}


я вот непонял насчет повторного вызова функции catFile() это обязательно?
++Norton++
Да, последующие вызовы тоже должны быть возможны.
Проверил код, первый вызов функции работает нормально, а вот последующие... такая же ситуация как и с моим кодом :(
Litkevich Yuriy
тогда перед выходом из функции вызывай либо void QTextStream::reset () либо bool QTextStream::seek ( qint64 pos ) с позицией нуль. Ни тот ни другой, я не использовал поэтому не знаю что тебе подойдет.
++Norton++
К сожалению, не то ни другое не подходит. Перед while пробовал ставить и in.seek(0) и in.reset(); но результат такой же... :(
Tonal
cat>file как бы тоже не перезапускается.
Так что приведённые функции работают совершенно аналогично.
Насколько я понимаю, шел по Ctrl+D просто закрывает пайп ввода, так что бессмысленно пытаться что-то ещё с ним зделать после этого.

Объясни ещё раз, чего именно ты пытаешся добиться?
Litkevich Yuriy
Tonal, посмотри пожалуйста тему QTextStream, operator<< работает асинхронно?, для меня поведение ввода/вывода неимеет объяснение
++Norton++
Tonal
Мне нужно написать функцию, которая бы считывала строку за строкой, введенные пользователем в stdin и потом, все то, что он вводил записалось в файл. При нажатии Enter, выполнение функции не должно прекращаться (как в любом текстовом редакторе. Это просто переход на следующую строку).
Т.е:
1. Вызывается функция и пользователь вводит в консоли (именно так, строку за строкой):
12345
67890
123123

2. Когда все написано, посылает сигнал о прекращении выполнения функции ( в моем случае это был ctrl+D, но полного успеха как видно нет).
3. Все то, что он ввел, записывается в файл (точно так же строка за строкой). Т.е. содержимое файла примет вид:
12345
67890
123123

Вот собственно и вся задача.
Litkevich Yuriy
++Norton++, дак тебе зачем вызывать функцию несколько раз?
При первом вызове, она съест все строчки и вывидит их в файл, см. мой пост №12, именно это и происходит, в виндовозе покрайней мере. Хоть там и нет <Ctrl>+<D>
++Norton++
Просто после выполнения этой функции не происходит выход из программы (передается управление опять функции main()). И если например пользователю нужно создать сразу же еще один текстовый файл (после создания первого), тогда нужно осуществить еще один вызов функции.
AD
Цитата(++Norton++)
Просто после выполнения этой функции не происходит выход из программы (передается управление опять функции main()). И если например пользователю нужно создать сразу же еще один текстовый файл (после создания первого), тогда нужно осуществить еще один вызов функции.

А что должно быть в этом 2 файле? То же самое, что в первом?
++Norton++
Нет, опять то, что введет пользователь. В общем когда функция main() считывает:
cat > name_file

Если ввод такой, то вызывается как раз эта функция catFile(); пользователь вводит данные (так, как я писал выше), нажимает ctrl+D, введенные данные сохраняются в файл name_file, и происходит возврат опять в функцию main. Здесь пользователь опять может ввести:
cat > name_file2

И повторить эту же процедуру, но в name_file2 ввести уже другие данные. Только это как раз и не получается. В этом втором вызове просто создается пустой файл name_file2 и происходит возврат в main().
Litkevich Yuriy
Цитата(++Norton++ @ 13.10.2008, 3:38) *
передается управление опять функции main()
а ты выйди из приложения и все
Tonal
2 ++Norton++ В твоём примере с cat-ами работают 2 программы: cat и шел.
когда ты запускаешь cat, шел открывает для него поток ввода.
При нажатии Ctrl+D шел закрывает поток ввода для текущей запущенной программы. cat ловит это как конец файла и завершается.
При повторном вызове cat-а, всё повторяется.

Т.е. если ты хочешь воспроизвести это поведение, тебе нужно или напрямую управлять терминалом и самому ловить Ctrl+D (по умолчанию его ловит шел), либо придумать какой-нибудь другой признак окончания ввода файла.
Например это может быт строка "EOF". Тогда твоя функция пишет файл, пока не считала эту спец.строку или конец файла.
Если считала конец файла - всё, если считала спец.строку - можно ещё раз запуститься и читать дальше.

П.С. На винде аналогом Ctrl+D является Ctrl+Z
П.П.С. По моему к Qt тема имеет весьма слабое отношение. Ей в "Техника программирования" место, или в "Другое". :)
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2024 IPS, Inc.