Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.57/7: Рейтинг темы: голосов - 7, средняя оценка - 4.57
1 / 1 / 1
Регистрация: 13.11.2015
Сообщений: 56
1

Как прочитать число из txt файла

14.11.2015, 18:55. Показов 1264. Ответов 6
Метки нет (Все метки)

Переискал весь интернет, поначалу всё было нормально, а потом builder стал считывать не то, что нужно. Цель: прочитать число из текстового документа (version.txt), в нем 1 или 2 и т.д., правда лучше с точкой, но пока не получается. Этот файл подгружаться будет из сети, затем нужно число сравнить с переменной в программе. Проблема в том, что в моем случае читается char, а сравнить нужно с int. Сначала делал StrToInt и работало нормально, а что произошло потом - непойму, получаю букву п вместо числа. Помогите пожалуйста, что можно придумать

C++
1
2
3
4
5
6
7
8
9
10
11
void __fastcall TForm1::Button1Click(TObject *Sender)
{
FILE *f;
 
  if(f=fopen((ExtractFilePath(Application->ExeName) + "version.txt").c_str(),"r"))
  {
    char t=fgetc(f);
    Memo1->Lines->Add(t);
 
  }
  fclose(f);
Добавлено через 15 минут
Нашел причину, она заключалась в неправильной кодировке текстового файла. Сменил с UTF-8 на ANSI и стало нормально, но есть еще несколько проблем.

Подскажите как прочитать строку, а не только 1 символ (например число 10, 110 и т.д.)?
Можно ли читать число с точкой и потом сравнивать, например float?
Еще один глупый вопрос - у меня в обработчике try{} catch{} идет проверка на доступность на сервере файла с версией, и если его там нет, то в version.txt попадает мусор с редиректа на страницу 404. (использую хостинг ucoz). Как можно добавить такую функцию, как очистку текстового файла и записи туда значения переменной из программы (currentversion)?

Прошу прощения за множество глупых вопросов.

Добавлено через 5 часов 32 минуты
Загружать сразу несколько символов (я ограничился 4-мя разрядами) получилось вот так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void __fastcall TForm1::Button1Click(TObject *Sender)
{
FILE *f;
 
  if(f=fopen((ExtractFilePath(Application->ExeName) + "version.txt").c_str(),"r"))
  {
    char t[5];
    while (fgets (t, 5, f) != NULL)
    {
                Memo1->Lines->Add(t);
                ShowMessage(t);
                if (StrToInt(t)==currentversion)
                 {
                 ShowMessage("Актуальная версия");
                 }
                }
  }
  fclose(f);
}
Остается вопрос как бы работать с float, хотя и так уже не плохо и самое важное как мне при необходимости - перезаписать version.txt в котором будет число из int currentversion?
0

Помощь в написании контрольных, курсовых и дипломных работ здесь.

Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
14.11.2015, 18:55
Ответы с готовыми решениями:

Прочитать число из изменённого файла, не возвращая файлу формат txt?
файл формата .txt содержащий число переименован в другой формат (.kjk) как можно прочитать число из...

Как прочитать параметр из файла txt?
Приветствую. Я вчера привинтил к своей программе отдельный в папке файл с конфигурацией, чтобы...

Как из txt файла прочитать только 3-ий ряд?
у меня есть txt file с названием lab ,как прочитать третию строку из него в листбокс и в текстбокс,...

Как прочитать определенную строку из txt файла
Как прочитать определенную строку из txt файла?

6
1 / 1 / 0
Регистрация: 09.09.2015
Сообщений: 22
14.11.2015, 19:27 2
Не понятен желаемый результат, но если следовать словам читаю из txt файла, то я за пятнадцать минут накидал вариант решения:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
 #include "vector"
std::vector<int>Integers;
std::vector<float>Floats;
 
bool Is_Digit_U(char Symbol) {
    if (Symbol >= '0' && Symbol <= '9')
        return true;
 
    return false;
};
 
void Add_Value(AnsiString &Text, bool &Is_Float) {
 
    if (Text.Length()) {
        if (Is_Float) {
            float Value = Text.ToDouble();
            Floats.push_back(Value);
            Is_Float = false;
 
        }
        else {
            int Value = Text.ToInt();
            Integers.push_back(Value);
        };
        Text = "";
    };
};
 
void __fastcall TForm1::FormCreate(TObject *Sender) {
 
    AnsiString Directory = GetCurrentDir() + "\\2.txt";
    std::auto_ptr<TFileStream>Stream(new TFileStream(Directory, fmOpenReadWrite));
    Stream->Seek(0, soFromBeginning);
    unsigned __int64 File_Size = Stream->Size;
    std::auto_ptr<char>_Buffer(new char[File_Size]);
    char * Buffer = _Buffer.get();
    Stream->Read(Buffer, File_Size);
 
    AnsiString Text;
    bool Is_Float = false;
    for (unsigned i = 0; i < File_Size; i++) {
 
        bool Is_Comma = Buffer[i] == ',';
        bool Is_Digit = Is_Digit_U(Buffer[i]);
 
        if (Is_Digit || Is_Comma) {
            Text += Buffer[i];
            if (Is_Comma)
                Is_Float = true;
        }
        else
            Add_Value(Text, Is_Float);
 
    };
 
    Add_Value(Text, Is_Float);
 
}
Соответственно в блокноте написаны:
34 567 67
343 6,56 45
2,222
И у меня получилось 5 целых и 2 числа с плавающей точкой в векторах.

Цитата Сообщение от Famous_47 Посмотреть сообщение
как бы работать с float
добавлю что при переводе из текста в цифру в тексте должна быть только запятая.
Цитата Сообщение от Famous_47 Посмотреть сообщение
перезаписать version.txt в котором будет число из int currentversion?
Непонятно что и как переписывать, что должно получится.
Самое простое решение - это в классе Stream вызывать функцию Stream->Write(...) и переписывать файл.

Добавлено через 2 минуты
Цитата Сообщение от Famous_47 Посмотреть сообщение
Прошу прощения за множество глупых вопросов.
Вопросы нормальные.
1
1 / 1 / 1
Регистрация: 13.11.2015
Сообщений: 56
14.11.2015, 23:39  [ТС] 3
Спасибо большое за ответ! С float попробую, код правда большой получается.. Пока собственными попытками смог (как уже писал выше) читать целые, просто увеличивая целое число на 1 при наличии новой версии программы.

Алгоритм проверки обновлений пока выглядит так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
void __fastcall TForm1::Button1Click(TObject *Sender)
// Проверка обновления программы
{
UpdErr=0;
TFileStream* FU = new TFileStream("version.txt", fmCreate | fmOpenWrite);
 try
 {
 HTTPUpd->Get("http://some_my_url/myprog/version.txt", FU);
 }
 catch (...)
 {
 UpdErr=1;
 ShowMessage("Обновления недоступны на данный момент");
 }
 delete FU;
  if (UpdErr==0)
  {
FILE *f;
 
  if(f=fopen((ExtractFilePath(Application->ExeName) + "version.txt").c_str(),"r"))
  {
    char t[5];
    while (fgets (t, 5, f) != NULL)
    {
                if (StrToInt(t)==currentversion)
                 {
                 ShowMessage("Установлена последняя версия");
                 }
                  if (StrToInt(t)>currentversion)
                  {
                  ShowMessage("Доступна новая версия");
                  }
                }
  }
  fclose(f);
  }
}
После обработки исключения catch(...) (провожу тест когда нет доступа к файлу version.txt на сервере) в файл version.txt который рядом с программой загружалось несколько строчек с html, с переадрессации на страницу 404. Была идея в случае, если доступ отсутствует, то после catch(...) добавить удаление файла version.txt и создание нового, с записыванием в него числа currentversion, которое инициализировано в самой программе, например равно 1. Но суть в том, что ошибка появляется только в builder'е, при получении 404, а в самой программе отрабатывает нормально исключение, а в следующий раз если доступ появляется то не смотря, что в файле мусор, качается новый - правильный и работает уже нормально)

На данном этапе всё теперь функционирует, на всё это меня сподвигла эта тема. Сейчас программа отлично проверяет наличие новой версии (качает файл, сравнивает в нем число с тем, что есть в программе), осталось реализовать сам процесс обновления exe. Необходимо решить как это реализовать в bat'нике или написать вторую часть программы. Еще одна программа вроде лучше вариант, но есть вопросы (так, еще раз извиняюсь, теперь за избыток текста)

Как посоветуете - сделать так, чтобы программа, которая удаляет старую, и переименовывает новую была постоянно рядом с основной? (опасаюсь, что если при ее несанкционированном запуске, без загрузки новой она может удалить основную программу, тут нужно создать проверку на наличие рядом myprog-new.exe и тогда давать ей сработать, а это я пока не умею)

Либо сделать подгрузку одновременно новой exe (основной программы) и программы, которая заменит старое на новое, но тогда это будет два запроса, не знаю логично ли делать так, чтобы было снова две обработки исключений, на случай если нет доступа к серверу?
0
1 / 1 / 0
Регистрация: 09.09.2015
Сообщений: 22
15.11.2015, 00:59 4
Я бы сделал так:
Создал пустой файл (в зависимости от инструментов выставить, чтобы размер файла был 0 байт, если это делать через new TFileStream(Directory, fmCreate), то там все нормально. Когда я делал через CreateFile и забывал выставлять каретку(SetFilePointer) и вызывать функцию SetEOF() у меня начинались проблемы).
Загрузить новую версию и сохранить как myprognew.exe(-#@ и подобные знаки лучше избегать)
При перезаписи старой версии на новую делать проверку размера файла TempNewProg.exe(Если размер файла 0 байт, значит загрузки не было и делать ничего не надо).
Если есть вероятность, что может загрузиться мусор и размер будет не 0 байт, то в version.txt можно еще записать размер нового файла (и контрольной суммы) и проверять эти значения вместе с версией.
Если все эти проверки соблюдаются, то ошибка исключается.
Цитата Сообщение от Famous_47 Посмотреть сообщение
создать проверку на наличие рядом myprog-new.exe
Такую проверку можно сделать так: FileExists(Directory);

Программу, которая обновляет главную программу, можно назвать Lancher.exe. Я такую фишку видел во многих приложениях.

Еще вспомнил про Float следующее решение:
#include "math.h"

char * Float_Text = "1.2";
float Value = atof(Float_Text);// можно и double

Цитата Сообщение от Famous_47 Посмотреть сообщение
while (fgets (t, 5, f) != NULL)
Почему while? Ведь если он сработает в первый раз, и файл будет больше 5 байт он будет читать файл до конца n количество раз. Можно же просто поставить if (fgets (t, 5, f) )
0
1 / 1 / 1
Регистрация: 13.11.2015
Сообщений: 56
15.11.2015, 14:24  [ТС] 5
Цитата Сообщение от Илья2 Посмотреть сообщение
Почему while?
Точно, спасибо.

С Float тоже сейчас поэксперементирую, большое спасибо за помощь! Уже вся система работает, загружает, обновляет, переименовывает... Осталась последняя преграда - с хостинга ucoz приходят битые exe. Пробовал переименовывать - тоже самое, там какойто редирект происходит... Нашел здесь описание этой проблемы, только там решение на C#, буду разбираться. Может есть какой-то хостинг с прямыми ссылками? Пробовал бесплатное фтп, с него труднее качать изза необходимости авторизации...
0
Практикантроп
4680 / 2600 / 496
Регистрация: 23.09.2011
Сообщений: 5,580
20.11.2015, 09:36 6
Цитата Сообщение от Famous_47 Посмотреть сообщение
Может есть какой-то хостинг с прямыми ссылками?
По моему и на ucoz это не проблема. Я делал там сайт и в нем прямые ссылки на zip-архив, и всё прекрасно грузится... .
0
1 / 1 / 1
Регистрация: 13.11.2015
Сообщений: 56
20.11.2015, 12:26  [ТС] 7
nick42, да, с этим разобрался, спасибо! Я переименовываю .exe в .tmp, а после загрузки обратно переименовываю, всё работает.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
20.11.2015, 12:26

Помощь в написании контрольных, курсовых и дипломных работ здесь.

Как прочитать дату из файла txt в matlab
Всем добрый день. Имеется массив данных в txt файле. Первый столбец - месяц и год. Второй...

как прочитать из файла .txt два значения которые через запятую
подскажите пожалуйста как прочитать из файла .txt два значения которые через запятую например : 10...

Как прочитать данные из txt- файла для последующей записи в ListBox1?
При нажатии на кнопку производится запись чисел из массива в текстовый документ через запятую,...

Как прочитать сразу два txt файла, в каждом из них находится массив строк?
Потом нужно будет объединить два массива в один.

Умножить введенное число на число из файла input.txt и сохранить ответ в файл output.txt
написать программу которая умножает введенное число на число из файла input.txt и сохраняет ответ в...

Вставка файла *.txt в символьном виде или как прочитать вставленный текст и дальнейший поиск в нём
Задание: задача по поиску. Дан текст в виде файла *.txt. Требуется найти какую-либо...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.