Всем привет!
Помогите разобраться, я запрашиваю файл *.txt с сервера
Он содержит 1 строку вида:
1 42500fd28e98c73a8b85c0b9ba0c0f57 ead084f7fe56a29ce4534117a7eb3fbf ea9bf8de9bf008dfc94ecde7260f4409
const char *response = httpClient.getString().c_str();
httpClient.end();
const char *esp_md5 = strchr(response, ' ') + 1;
const char *fs_md5 = strchr(esp_md5, ' ') + 1;
const char *mcu_md5 = strchr(fs_md5, ' ') + 1;
ota_latest = strtol(response, NULL, 10);
strncpy(ota_latest_esp_md5, esp_md5, 32);
ota_latest_esp_md5[32] = '\0';
strncpy(ota_latest_fs_md5, fs_md5, 32);
ota_latest_fs_md5[32] = '\0';
strncpy(ota_latest_mcu_md5, mcu_md5, 32);
ota_latest_mcu_md5[32] = '\0';
Переменные:
long ota_latest = VERSION;
char ota_latest_esp_md5[33] = "";
char ota_latest_fs_md5[33] = "";
char ota_latest_mcu_md5[33] = "";
Как эти данные разбить по пробелу и записать в соответствующие переменные? Данный вариант не работает.
Первый вариант:
// суем:
#include <string.h>
#include "string_array.h"
....
string response = httpClient.getString().c_str();
httpClient.end();
// создаем обьект:
StringArray z;
// разбиваем:
z.explode(" ", response);
// используем как хотим, например:
for(int i = 0; i < z.length(); ++i){
std::string s = z.get(i);
printf("строка номер %d такая: %s", i, s.c_str());
}
....
string_array.h:
//---------------------------------------------------------------------------
#ifndef string_arrayH
#define string_arrayH
#include <vcl.h>
#include <string>
#include <stdio.h>
#ifndef AS
#define AS AnsiString
#endif
AnsiString s2as(std::string a){
AS b = a.c_str();
return b;
}
std::string s2as(AS a){
std::string b = a.c_str();
return b;
}
AnsiString std_str2as(std::string a){
return s2as(a);
}
class StringArray{
public:
StringArray(){
len=0;
allocated=false;
}
void explode(std::string delim, std::string cont){
if(delim=="")return;
signed int sum=0;
signed int loc = - signed(delim.length());
signed int locs=0;
do{
locs = loc+delim.length();
loc = cont.find( delim, locs);
sum++;
}while(loc != std::string::npos);
if(allocated){
delete [] strs;
}
strs = new std::string[sum];
len = sum;
allocated=true;
if(cont.find( delim, 0) == std::string::npos){
strs[0] = cont;
return;
}
// now parcing again and putting all the parts:
sum = 0;
loc = - signed(delim.length());
do{
locs = loc+delim.length();
loc = cont.find( delim, locs);
strs[sum] = cont.substr(locs, loc-locs);
sum++;
}while(loc != std::string::npos);
}
std::string implode(std::string delim=""){
std::string r="";
if(!allocated)return "ERROR:not allocated";
int i;
for(i=0;i<length()-1;++i){
r+=strs[i]+delim;
}
return r+strs[i];
}
void dump(){
printf("\nelemelts num: %d\n", len);
if(!allocated)return;
for(int i=0;i<length();++i){
printf("str[%d] = %s\n", i, strs[i].c_str());
}
}
std::string str(int i){
if(allocated && i>=0 && i < length())
return strs[i];
return "";
}
std::string get(int i){ return str(i); }
int length(){ return len; }
private:
bool allocated;
int len;
std::string *strs;
};
// и как бонус - функция - точный аналог phpшной str_replace:
AS str_replace(AS search, AS replace, AS s){
if(!s.Pos(search)) return s;
StringArray sa;
sa.explode(s2as(search), s2as(s));
return s2as(sa.implode(s2as(replace)));
}
//---------------------------------------------------------------------------
#endif
Второй более изящный, мне больше нравится:
#include <iostream>
#include <vector>
#include <string>
// ...другие хедеры
std::vector<std::string> explode(std::string str, char delim = ' ');
void main()
{
// .. твой код
string response = httpClient.getString().c_str();
httpClient.end();
vector<string> v = explode(" ", str);
for(int i=0; i<v.size(); i++)
cout <<i << " ["<< v[i] <<"] " <<endl;
}
std::vector<std::string> explode(std::string str, char delim = ' ') {
std::vector<std::string> result;
std::stringstream stream(str);
std::string buffer = "";
while (std::getline(stream, buffer, delim)) {
result.push_back(buffer);
}
return result;
}
Запустил данный код, и всё работает.
#include <stdio.h>
#include <string.h>
int main()
{
char ota_latest_esp_md5[33] = "";
char ota_latest_fs_md5[33] = "";
char ota_latest_mcu_md5[33] = "";
const char *response = "1 42500fd28e98c73a8b85c0b9ba0c0f57 ead084f7fe56a29ce4534117a7eb3fbf ea9bf8de9bf008dfc94ecde7260f4409";
const char *esp_md5 = strchr(response, ' ') + 1;
const char *fs_md5 = strchr(esp_md5, ' ') + 1;
const char *mcu_md5 = strchr(fs_md5, ' ') + 1;
//ota_latest = strtol(response, NULL, 10);
strncpy(ota_latest_esp_md5, esp_md5, 32);
ota_latest_esp_md5[32] = '\0';
strncpy(ota_latest_fs_md5, fs_md5, 32);
ota_latest_fs_md5[32] = '\0';
strncpy(ota_latest_mcu_md5, mcu_md5, 32);
ota_latest_mcu_md5[32] = '\0';
printf("1 - %s\n", ota_latest_esp_md5);
printf("2 - %s\n", ota_latest_fs_md5);
printf("3 - %s\n", ota_latest_mcu_md5);
return 0;
}
Чтобы прочитать из файла разделённые пробелом значения в отдельные переменные, можно operator>>(std::basic_istream)
использовать:
const size_t N = 33;
file >> ota_latest
>> std::setw(N) >> ota_latest_esp_md5
>> std::setw(N) >> ota_latest_fs_md5
>> std::setw(N) >> ota_latest_mcu_md5;
Это работает для обычных файлов:
std::ifstream file("input.txt");
для строки:
std::string s = "1 42500fd28e98c73a8b85c0b9ba0c0f57 ead084f7fe56a29ce4534117a7eb3fbf ea9bf8de9bf008dfc94ecde7260f4409";
std::stringstream file(s);
В общем случае HTTP клиент может тело ответа также в виде потока отдать:
Poco::URI uri {"http://example.com/input.txt"};
Poco::Net::HTTPStreamFactory factory;
std::unique_ptr<std::istream> pFile(factory.open(uri));
// std::istream& file = *pFile;
Виртуальный выделенный сервер (VDS) становится отличным выбором
Добрый деньПытаюсь решить одну задачу, надо, чтобы читались данные из файла
Есть задача: вводится просто строка с цифрами и пробелами и задача вычленить из неё цифры для последующих с ними манипуляций(желательно в int)Например...
Где в VS можно указать версию приложения или библиотеки разработанной на С++?
Здравствуйте, как на с/с++ написать нерекурсивный обход бинарного дерева через стек методом post-order (сначала листья, потом корень)?