[英]getting garbage characters while reading from file
I have a CS project and I am trying to write/read strings into a string
variable, say x
of size 10. I am new to coding, and I am making some mistake with writing to file. 我有一个CS项目,我试图将字符串写入/读取一个string
变量,比如说x
的大小为10。我是编码的新手,并且在写入文件时犯了一些错误。 Please help me. 请帮我。
Here is the class I have defined in my project file that includes my string x[10]
array. 这是我在项目文件中定义的类,其中包括我的string x[10]
数组。 I am pretty sure that I am making a mistake in writing to file, because it adds garbage characters in the file. 我很确定我在写入文件时犯了一个错误,因为它在文件中添加了垃圾字符。
void write_announcement()
{
student st;
string line;
int num;
ofstream file;
file.open("announcement.txt");
cout << "Enter number:";
cin >> num;
cin.ignore();
getline(cin,line);
announce[num] = line;
file.write(reinterpret_cast<char *> (&st), sizeof(student));
file.close();
}
void read_announcement()
{
student st;
int n;
cout << "Enter n: ";
cin >> n;
ifstream file;
file.open("announcement.txt");
while (file >> st.announce[n]);
{
cout << announce[n];
}
file.close();
}
You can't write/read a std::string
object as-is to/from a stream, let alone an array of strings, the way you are doing so. 您不能按原样向流中写入/读取std::string
对象,更不用说按这种方式来处理字符串数组了。 You are writing/reading each string's internal data, which amongst other things consists of a pointer to character data that is stored elsewhere in memory, possibly a small buffer for short-string optimizations, etc. You are writing/reading that internal data, not the actual character data. 您正在写入/读取每个字符串的内部数据,其中包括指向存储在内存中其他位置的字符数据的指针,可能是用于短字符串优化的小缓冲区等。您正在写入/读取该内部数据,而不是实际字符数据。 That is why you are getting "garbage" in your file. 这就是为什么您的文件中出现“垃圾”的原因。
When writing, you need to serialize the string character data in a format that you can then deserialize when reading back, eg: 写入时,您需要以一种格式对字符串数据进行序列化 ,然后在回读时可以反 序列化该格式,例如:
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;
}
Alternatively: 或者:
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;
}
That being said, you are creating a new local student
every time you write/read the file, but you populate only 1 string on each write, and are not preserving previous strings across multiple writes. 话虽这么说,您每次写入/读取文件时都在创建一个新的本地student
,但是每次写入仅填充一个字符串,并且不会在多次写入中保留以前的字符串。 So, either: 因此,要么:
read the file to load previous strings before then assigning and writing new strings. 在分配和写入新字符串之前,请先读取文件以加载先前的字符串。
make the student
be a global variable so it exists longer than any single write/read operation, and thus can cache string assignments over time. 使student
成为全局变量,因此它的存在时间比任何单个写/读操作的时间都长,因此可以随时间缓存字符串分配。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.