Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > [qt] считывание данных из файла


Автор: kuvshinka 24.9.2010, 23:50
Допустим есть текстовый файл params.txt, расположенный в папке с экзешником программы и имеющий следующее содержание:

//commentarii
1  //Это параметр1
2  //Это параметр2
20100
“hello”
“preved”
5

Подскажите пож-та примером smile  каким простейшим способом можно сосчитать это содержимое файла (значения 1,2,20100, "hello", "preved" и 5) в переменные соответственно типа int, int, int, QString, QString, int или в массив QString[6]-ов???

Автор: RedDigger 25.9.2010, 00:11
Код

#include <QApplication>
#include <QtCore/QFile>
#include <QtCore/QTextStream>
#include <QtCore/QStringList>
#include <QDebug>
int main(int argc,char** argv) {

    QApplication app(argc,argv);

    QFile file("./test.in");
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
        return 1;
    QTextStream in(&file);

    QString line = in.readLine();
    QStringList result;
    while (!line.isNull()) {
        line.remove(QRegExp("//[\\W\\w]{0,}"));
        result.append(line);
        line = in.readLine();
    }
    qDebug() << result;
}




Но на будущее если хочешь создавать проекты тебе придется писать самому а не просить примеров на форумах... 
Удачи

Автор: kuvshinka 26.9.2010, 11:08
RedDigger: smile  спасибо большое за помощь - в принципе я все поняла, остался один вопрос - как в итоговый элемент StringList-a запомнить только значение строки строго до разделительного символа (табуляция или просто пробел) между самим значением и его комментарием?
то есть:
в файле строка:445 //параметр1   
в StringList-е: "445" без конечного пробела или табуляции после 445 - то есть чисто "445"
как надо изменить регулярное выражение в QRegExp?
подскажите пож-та... smile 

Автор: admsasha 26.9.2010, 12:00
Если не ошибаюсь, то так:
Код
line.remove(QRegExp("(\\s)*(\\t)*$"));


или так
Код
 line.remove(QRegExp("(\\s|\\t)$"));


ну или так
Код

line.remove(QRegExp("(\\s)*(\\t)*//[\\W\\w]{0,}"));

Автор: RedDigger 26.9.2010, 15:35
Цитата(kuvshinka @ 26.9.2010,  11:08)
RedDigger: smile  спасибо большое за помощь - в принципе я все поняла, остался один вопрос - как в итоговый элемент StringList-a запомнить только значение строки строго до разделительного символа (табуляция или просто пробел) между самим значением и его комментарием?
то есть:
в файле строка:445 //параметр1   
в StringList-е: "445" без конечного пробела или табуляции после 445 - то есть чисто "445"
как надо изменить регулярное выражение в QRegExp?
подскажите пож-та... smile

Если честно то я не понял вопроса.. 
Добавлю к предыдущим примерам парочку собственных...
1. Если тебе не надо удалять комментарии со строки то тогда просто удали строку с QRegExp....
2. Если тебе надо использовать другой разделитель, но при этом результат с разделителем "//" тебя устраивает - просто замени эти два символа в строке маски внутри QRegExp на необходимый тебе.. Только будь внимательна - Не все символы отыгрываются так как это кажется с первого взгляда.. Загляни в http://doc.qt.nokia.com/4.6/qregexp.html чтобы понять о использовании регулярных выражений.
3. Если тебе необходимо использовать "//" не как комментарий (удаление из информации его и все что в строке после) а как разделитель строки (из одной строки содержащей 1 или более выражений "//" получить 2 или более строк) - тогда вместо
Код

        line.remove(QRegExp("//[\\W\\w]{0,}"));
        result.append(line);

поставь следующую строку

Код

        result.append(line.split(QString("__MY_DELIMETER__")));

Естественно заменив __MY_DELIMETER__ на значение твоего разделителя..

Надеюсь помог.

Автор: kuvshinka 26.9.2010, 16:56
admsasha:
спасибо за подсказку:
Код

line.remove(QRegExp("(\\s)*(\\t)*//[\\W\\w]{0,}"));

дает нужный мне результат   smile   - в i-ый элемент списка заносится весь текст i-ой строки текстового файла СТРОГО ДО символа(ов) пробела или табуляции...
RedDigger тоже спасибо... еще раз... smile   

Автор: kuvshinka 29.9.2010, 19:11
Теперь у меня проблема в указании пути к текстовому файлу – надо задавать ПОЛНЫЙ путь к файлу (хотя если указано только имя файла, то он ведь должен искаться в папке с пусковым файлом):
допустим каталог программы расположен в /home/Anna/Desktop/Test_primer, пробую:
 
Код

ui->lineEdit>setText(QDir::current().absolutePath() );

запуск проги из креатора дает верный ответ -  /home/Anna/Desktop/Test_primer
запуск экзешника кликом на нем – ответ  всего лишь /home/Anna – ПОЧЕМУ и как сие исправить? Работаю под Linux OpenSuse 10.3, Qt 4.6.1...в винде все нормально работает…

Автор: RedDigger 29.9.2010, 19:22
Цитата(kuvshinka @ 29.9.2010,  19:11)
Теперь у меня проблема в указании пути к текстовому файлу – надо задавать ПОЛНЫЙ путь к файлу (хотя если указано только имя файла, то он ведь должен искаться в папке с пусковым файлом):
допустим каталог программы расположен в /home/Anna/Desktop/Test_primer, пробую:
 
Код

ui->lineEdit>setText(QDir::current().absolutePath() );

запуск проги из креатора дает верный ответ -  /home/Anna/Desktop/Test_primer
запуск экзешника кликом на нем – ответ  всего лишь /home/Anna – ПОЧЕМУ и как сие исправить? Работаю под Linux OpenSuse 10.3, Qt 4.6.1...в винде все нормально работает…

QDir::current() - возращает рабочий адрес приложения. (Например находясь в папке /tmp ты запускаешь приложение выводящее тебе QDir::current() - оно вернет именно /tmp а не тот адрес где оно расположено..)

Тебе надо использовать следующую функцию - http://doc.trolltech.com/3.3/qapplication.html#applicationDirPath

Автор: kuvshinka 30.9.2010, 21:16
RedDigger: у меня очередная проблема - как Вы показали выше считала данные из тектового файла - первая строка в стринглисте result равна "192.132.12.10" (это верно) - мне ее надо  передать (использовать) в метод другого модуля в качестве параметра типа  (char *) - пробую это сделать так:
Код

result.at(1).toAscii().data()

 вроде ошибок не выдает, но на приемной стороне значение - абракадабра какая-то в зависимости от используемой кодировки (в примере - toAscii)....как тут быть?

Автор: SABROG 30.9.2010, 23:04
Покажите код. 

Ваш код создает временную строковую переменную QByteArray с копией строки и на этой же линии строковая временная переменная грохается при выходе из области видимости. Таким образом указатель на строку становится невалидным при переходе к следующей инструкции.

Код

result.at(1).toAscii().data()

Автор: kuvshinka 2.10.2010, 14:02
SABROG: по Ваше просьбе выкладываю максимально упрощенный (и все равно неработающий верно) мой код - см. приложенный к письму архив проги...
в проекте: в методе Connect_params, если задать первый передаваемый параметр (IP-адрес) в виде константы, а не считанный из текстового файла, то все правильно работает, в противном случае - считываемый IP-параметр неверно воспринимается в методах модуля en_vit1...
подскажите пож-та...желательно с минимально нужными исправлениями smile ...а то я уже второй день бьюсь над этой задачкой... smile 

Автор: admsasha 2.10.2010, 14:27
kuvshinka

1.
твой пример выдает у меня "257.223.62.32"
Код

$ ./primerr
257.223.62.32


Может прога не видит твой txt файл ? Например, у меня бинарник собрался в корне с исходниками, а твой txt находится в папке release

2. 
судя по текстовику, это у тебя конфиг. А почему бы не использовать тогда  QSettings ?

Автор: kuvshinka 2.10.2010, 18:12
у меня бинарник собирается (появляется) в папке Release - там же лежит и текстовый файл...после запуска проги из creator-а   выдается какой-то странный ответ - то какое-то "5р", то квадратик, то  257.223.62.32... почему ответ в принципе меняется? что за класс QSettings? никогда его не использовала...подскажите программно как его тут можно применить?
общая задача такая - работающий отдельно от проекта бинарник (Qt 4.6 собран статически в версии Release) программы должен при своем запуске считывать данные из текстового файла и использовать их в разных своих модулях...

Автор: SABROG 2.10.2010, 18:54
Тут при переходе на следующую инструкцию указатель возвращенный data() становится невалидным, т.к. временный объект QByteArray уничтожается при выходе из области видимости.
Код

    struct A tt[]={{file_params.at(1).toAscii().data(), 100}};  // если задать константой первый параметр (IP-адрес) - все верно передаетcя!!!!


Получить указатель на данные в ASCII формате из QString без копирования самого текста невозможно из-за того, что QString содержит текст в Unicode кодировке. Единственным выходом, видимо, будет объявление постоянной QByteArray переменной где нибудь в MainWindow.

Автор: kuvshinka 2.10.2010, 21:35
SABROG: ммм....ну объявила я переменную QByteArray ip; в классе MainWindow....и что дальше делать - в той же функции Connect_params записать в ip считанную из файла нужную мне строку?:
Код

  ip.append(file_params.at(1));

а как мне потом ее преобразовать к типу (char *) для записи в передаваемую структуру A?
Код

 struct A tt[]={{ip.at(0).toAscii() , 100}};  !!! НЕ РАБОТАЕТ

Автор: SABROG 3.10.2010, 22:56
Цитата(kuvshinka @ 2.10.2010,  21:35)
Код

 struct A tt[]={{ip.at(0).toAscii() , 100}};  !!! НЕ РАБОТАЕТ

toAscii() возвращает тот самый QByteArray, который должен существовать пока есть необходимость в указателе на char* полученный методом data().

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)