#include <iostream>
#include <vector>
#include <stdio.h>
using namespace std;
struct t{
string nazv;
int semestr;
vector <int> a;
t()
};
t::t(){
this->nazv = "default name";
this->semestr = 1;
this->a.push_back(1);
}
int main()
{
setlocale(LC_ALL, "Rus");
cout <<" введите количество предметов\n";
int n; //количество предметов
cin>>n;
for (int i=0;i<n;i++){
int tmp;
t name;
cout <<"введите название предмета\n";
cin>> name.nazv;
cout << "введите количество семестров\n";
cin>> name.semestr ;//cin >> name.a ;
for (int i=0;i<name.semestr;i++){
cout << "введите номера семестров\n";
cin>>tmp;
name.a.push_back(tmp);
}
FILE * f;
f = fopen("5.txt", "wb+");
fwrite(&name, sizeof(name), 1, f);
fclose(f);
}
} std::string и std::vector<int>. Расскажи про эти типы, как они работают, какая у них методология управления памятью. Частью какой библиотеки являются эти типы? К какой подсистеме этой библиотеки данные типы относятся?fwrite?fwrite, и на каком именно языке реализованы шаблоны std::basic_string и std::vector?
fwrite реализована на языке C и является частью file i/o API. std::basic_string является частью Strings Library, а std::vector - частью Container Library в Standard Template Library, реализованной на языке C++.fwrite(&name, sizeof(name), 1, f);nazv или a не хранится, там хранятся только указатели на выделенную память + довольно много сервисных полей. Даже учитывая SSO нельзя говорить что данные самой строки размещаются внутри объекта std::string, т.к. в общем смысле это не так.fwrite(&name.nazv, sizeof(string), 1,f);
fwrite(&name.semestr, sizeof(int), 1,f);
fwrite(&name.a, sizeof(name.a), 1,f);fwrite, откуда ей на самом деле стоит брать память для формирования нужного тебе формата файла. Эта функция ничего не знает о строках и типах, о размещении в памяти и структуре того или иного объекта. Она принимает просто кусок памяти и пишет его в файл по текущей позиции в файле. Все.std::string и std::vector в интерфейсе есть функция data (для строки, для вектора) для получения указателя на подконтрольную память. В случае строки ты эту память можешь писать сразу в файл. В случае вектора от int - тоже, т.к. с фундаментальными типами все довольно просто.
#include<iostream>
#include<fstream>
#include<string>
#include<vector>
using namespace std;
struct Data
{
unsigned size;
string header;
Data(string s = {}) : size(s.size()), header(s)
{
//...
}
};
ifstream& operator>>(ifstream& is, Data& block)
{
is.read(reinterpret_cast<char*>(&block.size), sizeof(block.size));
block.header.resize(block.size);
is.read(block.header.data(), block.size);
return is;
}
ofstream& operator<<(ofstream& os, Data& block)
{
os.write(reinterpret_cast<char*>(&block.size), sizeof(block.size));
os.write(block.header.data(), block.size);
return os;
}
struct Storage
{
string file;
vector<Data> data;
Storage(string filename) : file(filename)
{}
Storage(string filename, const vector<Data>& data) : file(filename), data{data}
{
}
void readData(ios_base::openmode);
void saveData(ios_base::openmode);
void printData();
void clear();
};
void Storage::readData(ios_base::openmode mode)
{
ifstream ifs(file, mode);
if(!ifs)
{
cerr << "Error..." << endl;
return;
}
Data value;
if(ios_base::binary == mode)
{
while(ifs >> value)
{
data.push_back(value);
}
}
else
{
while(ifs >> value.size)
{
ifs >> value.header;
data.push_back(value);
}
}
cout << data.size() << "\tBlocks read" << endl;
}
void Storage::saveData(ios_base::openmode mode)
{
ofstream ofs(file, mode);
if(!ofs)
{
cerr << "Error..." << endl;
return;
}
if(ios_base::binary == mode)
{
for(auto& v : data)
{
ofs << v;
}
}
else
{
for(const auto& v : data)
{
ofs << v.size << " " << v.header << "\n";
}
}
cout << data.size() << "\tBlocks written" << endl;
}
void Storage::printData()
{
cout << "\nData size: " << data.size() << "\n";
for(const auto& v : data)
{
cout << "Header:\t" << v.header << "\tSize:\t" << v.size << "\n";
}
cout << endl;
}
void Storage::clear()
{
data.clear();
data.shrink_to_fit();
cout << "\nclear..." << endl;
}
int main()
{
vector<Data> myDataVec = {{"one"}, {"two"}, {"three"}};
Storage store("D:\\mydata.to", myDataVec);
store.printData();
store.saveData(ios_base::out);
//store.saveData(ios_base::binary);
store.clear();
store.printData();
store.readData(ios_base::in);
//store.readData(ios_base::binary);
store.printData();
}