我有一个CS项目,我正在尝试将字符串写入/读取到大小为{10的string
的{{1}}变量中。我是编码新手,在编写时犯了一些错误归档。请帮助我。
这是我在项目文件中定义的包含x
数组的类。我很确定我在写入文件时犯了一个错误,因为它在文件中添加了垃圾字符。
string x[10]
答案 0 :(得分:1)
您不能像往流中那样从流中写入/读取std::string
对象 ,更不用说字符串数组了。您正在写入/读取每个字符串的内部数据,其中包括指向存储在内存中其他位置的字符数据的指针,可能是用于短字符串优化的小缓冲区等。您正在写入/读取该内部数据,而不是实际字符数据。这就是为什么您的文件中出现“垃圾”的原因。
写入时,您需要以一种字符串格式序列化,然后在读回时可以反序列化的格式,例如:
struct student
{
string announce[10];
};
ostream& operator<<(ostream &os, const student &st)
{
for(int x = 0; x < 10; ++x)
os << st.announce[x] << '\n';
return os;
}
istream& operator>>(istream &is, student &st)
{
for(int x = 0; x < 10; ++x)
getline(is, st.announce[x]);
return is;
}
void write_announcement()
{
student st;
string line;
int num;
cout << "Enter number: ";
cin >> num;
cin.ignore(numeric_limits<streamsize>::max(), '\n');
if ((num < 0) || (num >= 10))
{
cout << "Invalid number!" << endl;
return;
}
cout << "Enter text: ";
getline(cin, line);
st.announce[num] = line;
ofstream file("announcement.txt");
if (!file.is_open())
{
cout << "Cannot create file!" << endl;
return;
}
if (!(file << st))
{
cout << "Cannot write to file!" << endl;
}
}
void read_announcement()
{
student st;
int num;
cout << "Enter number: ";
cin >> num;
cin.ignore(numeric_limits<streamsize>::max(), '\n');
if ((num < 0) || (num >= 10))
{
cout << "Invalid number!" << endl;
return;
}
ifstream file("announcement.txt");
if (!file.is_open())
{
cout << "Cannot open file!" << endl;
return;
}
if (!(file >> st))
{
cout << "Cannot read from file!" << endl;
return;
}
cout << "Text: " << st.announce[num] << endl;
}
或者:
struct student
{
string announce[10];
};
ostream& operator<<(ostream &os, const student &st)
{
for(int x = 0; x < 10; ++x)
{
uint32_t len = st.announce[x].size();
os.write(reinterpret_cast<char*>(&len), sizeof(len));
os.write(st.announce[x].c_str(), len);
}
return os;
}
istream& operator>>(istream &is, student &st)
{
for(int x = 0; x < 10; ++x)
st.announce[x].clear();
for(int x = 0; x < 10; ++x)
{
uint32_t len;
if (!is.read(reinterpret_cast<char*>(&len), sizeof(len))) break;
string s;
if (len > 0)
{
s.resize(len);
if (!is.read(&s[0], len)) break;
}
st.announce[x] = s;
}
return is;
}
void write_announcement()
{
student st;
string line;
int num;
cout << "Enter number: ";
cin >> num;
cin.ignore(numeric_limits<streamsize>::max(), '\n');
if ((num < 0) || (num >= 10))
{
cout << "Invalid number!" << endl;
return;
}
cout << "Enter text: ";
getline(cin, line);
st.announce[num] = line;
ofstream file("announcement.txt", ofstream::binary);
if (!file.is_open())
{
cout << "Cannot create file!" << endl;
return;
}
if (!(file << st))
{
cout << "Cannot write to file!" << endl;
}
}
void read_announcement()
{
student st;
int num;
cout << "Enter number: ";
cin >> num;
cin.ignore(numeric_limits<streamsize>::max(), '\n');
if ((num < 0) || (num >= 10))
{
cout << "Invalid number!" << endl;
return;
}
ifstream file("announcement.txt", ifstream::binary);
if (!file.is_open())
{
cout << "Cannot open file!" << endl;
return;
}
if (!(file >> st))
{
cout << "Cannot read from file!" << endl;
return;
}
cout << "Text: " << st.announce[num] << endl;
}
话虽如此,您每次写入/读取文件时都在创建一个新的本地student
,但是每次写入仅填充1个字符串,并且不会在多次写入中保留先前的字符串。因此,要么:
读取文件以加载先前的字符串,然后分配和写入新的字符串。
使student
为全局变量,因此它的存在时间比任何单个写入/读取操作的时间都长,因此可以随时间缓存字符串分配。