++Norton++
11.10.2008, 13:17
Есть функция, которая выполняет запись в файл:
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)). Что может быть не так?
Ну насколько я понимаю, тебе следует каким-нибудь образом указать потоку ввода stdin, чтобы он переместил указатель на начало и считывал введенные данные по новой. Как именно, почитай QIODevice, QFile.
Litkevich Yuriy
11.10.2008, 16:45
Цитата(++Norton++ @ 11.10.2008, 17:17)
while(!in.atEnd())
{
content.append(in.readLine()+"\n");
}
вот эти строчки объясни.
И чё тут странного?
Ты в первый раз выгребаешь всё из stdin.
Во второй запуск там естественно уже ничего нет - он как встал в режим atEnd в первый раз, так там и стоит.
++Norton++
11.10.2008, 22:28
Litkevich Yuriy, эта строчка читает со стандартного ввода линию и заносит ее в QStringList.
На счет режима atEnd()... а можно как-нибудь вывести из этого режима, чтобы и при последующих запусках все работало как надо?
Цитата(++Norton++ @ 11.10.2008, 23:28)
Litkevich Yuriy, эта строчка читает со стандартного ввода линию и заносит ее в QStringList.
На счет режима atEnd()... а можно как-нибудь вывести из этого режима, чтобы и при последующих запусках все работало как надо?
Объясните корректно, пожалуйста, чего Вы хотите добиться. Неясно какой результат нужен!
)))
Litkevich Yuriy
11.10.2008, 22:40
Цитата(++Norton++ @ 12.10.2008, 2:28)
со стандартного ввода линию и
читает строку, а сама строка чем заканчивается? <Ctrl>+<D>? т.е. это не прерывает ввод данных, а только сигналит о завершении строки?
Я так понимаю ты все это делаешь в GNU/Linux
Цитата(AD @ 12.10.2008, 2:34)
Объясните корректно, пожалуйста, чего Вы хотите добиться. Неясно какой результат нужен! )))
Присоеденяюсь.
Лучше объясни каков должен быть результат работы модуля/программы, возможно все проще.
++Norton++
11.10.2008, 22:44
Да, все делаю в Linux.
Просто нужна функция, которая работала бы аналогично линуксовой команде (cat > file.name). Т.е. читала строку за строкой что вводит пользователь и потом записывала в файл. Если пользователь нажимает Enter, нужно просто перейти на следующую строку, но не закончить выполнение. Закончить выполнение нужно тогда, когда пользователь нажмет ctrl+D.
Цитата(++Norton++ @ 11.10.2008, 23:44)
Да, все делаю в Linux.
Просто нужна функция, которая работала бы аналогично линуксовой команде (cat > file.name). Т.е. читала строку за строкой что вводит пользователь и потом записывала в файл. Если пользователь нажимает Enter, нужно просто перейти на следующую строку, но не закончить выполнение. Закончить выполнение нужно тогда, когда пользователь нажмет ctrl+D.
Хорошо, а как она делает по тому коду, что здесь был приведен? Не работаю в Линукс, поэтому смогу помочь, когда узнаю все подробности!
)))
Litkevich Yuriy
11.10.2008, 23:00
Цитата(++Norton++ @ 12.10.2008, 2:44)
Если пользователь нажимает Enter, нужно просто перейти на следующую строку, но не закончить выполнение. Закончить выполнение нужно тогда, когда пользователь нажмет ctrl+D.
А разве ввод не прекращается при нажатии <Enter>?
++Norton++
11.10.2008, 23:06
В том то и дело, что просто переходит на другую линию (так, в принципе, и надо).
Litkevich Yuriy
11.10.2008, 23:21
ну я кажется просто торможу, вот такой код попробуй:
#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++
12.10.2008, 0:41
Да, последующие вызовы тоже должны быть возможны.
Проверил код, первый вызов функции работает нормально, а вот последующие... такая же ситуация как и с моим кодом
Litkevich Yuriy
12.10.2008, 0:46
тогда перед выходом из функции вызывай либо void QTextStream::reset () либо bool QTextStream::seek ( qint64 pos ) с позицией нуль. Ни тот ни другой, я не использовал поэтому не знаю что тебе подойдет.
++Norton++
12.10.2008, 11:22
К сожалению, не то ни другое не подходит. Перед while пробовал ставить и in.seek(0) и in.reset(); но результат такой же...
cat>file как бы тоже не перезапускается.
Так что приведённые функции работают совершенно аналогично.
Насколько я понимаю, шел по Ctrl+D просто закрывает пайп ввода, так что бессмысленно пытаться что-то ещё с ним зделать после этого.
Объясни ещё раз, чего именно ты пытаешся добиться?
Litkevich Yuriy
12.10.2008, 15:49
Tonal, посмотри пожалуйста тему
QTextStream, operator<< работает асинхронно?, для меня поведение ввода/вывода неимеет объяснение
++Norton++
12.10.2008, 22:22
Tonal
Мне нужно написать функцию, которая бы считывала строку за строкой, введенные пользователем в stdin и потом, все то, что он вводил записалось в файл. При нажатии Enter, выполнение функции не должно прекращаться (как в любом текстовом редакторе. Это просто переход на следующую строку).
Т.е:
1. Вызывается функция и пользователь вводит в консоли (именно так, строку за строкой):
12345
67890
123123
2. Когда все написано, посылает сигнал о прекращении выполнения функции ( в моем случае это был ctrl+D, но полного успеха как видно нет).
3. Все то, что он ввел, записывается в файл (точно так же строка за строкой). Т.е. содержимое файла примет вид:
12345
67890
123123
Вот собственно и вся задача.
Litkevich Yuriy
12.10.2008, 22:28
++Norton++, дак тебе зачем вызывать функцию несколько раз?
При первом вызове, она съест все строчки и вывидит их в файл, см. мой пост №12, именно это и происходит, в виндовозе покрайней мере. Хоть там и нет <Ctrl>+<D>
++Norton++
12.10.2008, 23:38
Просто после выполнения этой функции не происходит выход из программы (передается управление опять функции main()). И если например пользователю нужно создать сразу же еще один текстовый файл (после создания первого), тогда нужно осуществить еще один вызов функции.
Цитата(++Norton++)
Просто после выполнения этой функции не происходит выход из программы (передается управление опять функции main()). И если например пользователю нужно создать сразу же еще один текстовый файл (после создания первого), тогда нужно осуществить еще один вызов функции.
А что должно быть в этом 2 файле? То же самое, что в первом?
++Norton++
13.10.2008, 0:00
Нет, опять то, что введет пользователь. В общем когда функция main() считывает:
cat > name_file
Если ввод такой, то вызывается как раз эта функция catFile(); пользователь вводит данные (так, как я писал выше), нажимает ctrl+D, введенные данные сохраняются в файл name_file, и происходит возврат опять в функцию main. Здесь пользователь опять может ввести:
cat > name_file2
И повторить эту же процедуру, но в name_file2 ввести уже другие данные. Только это как раз и не получается. В этом втором вызове просто создается пустой файл name_file2 и происходит возврат в main().
Litkevich Yuriy
13.10.2008, 2:07
Цитата(++Norton++ @ 13.10.2008, 3:38)
передается управление опять функции main()
а ты выйди из приложения и все
2 ++Norton++ В твоём примере с cat-ами работают 2 программы: cat и шел.
когда ты запускаешь cat, шел открывает для него поток ввода.
При нажатии Ctrl+D шел закрывает поток ввода для текущей запущенной программы. cat ловит это как конец файла и завершается.
При повторном вызове cat-а, всё повторяется.
Т.е. если ты хочешь воспроизвести это поведение, тебе нужно или напрямую управлять терминалом и самому ловить Ctrl+D (по умолчанию его ловит шел), либо придумать какой-нибудь другой признак окончания ввода файла.
Например это может быт строка "EOF". Тогда твоя функция пишет файл, пока не считала эту спец.строку или конец файла.
Если считала конец файла - всё, если считала спец.строку - можно ещё раз запуститься и читать дальше.
П.С. На винде аналогом Ctrl+D является Ctrl+Z
П.П.С. По моему к Qt тема имеет весьма слабое отношение. Ей в "Техника программирования" место, или в "Другое".
Для просмотра полной версии этой страницы, пожалуйста,
пройдите по ссылке.