写入文件,读取时分隔值
Writing to a File, Separating Values when Reading
我正在尝试自学编程,而我难以理解的一个早期主题是文件 IO。
到目前为止,我知道我可以保存用逗号分隔的数据,以便以后成功读取该数据。执行以下操作:
int x[] = {1,22,333,4444,55555};
std::ofstream FileWriter;
std::string dataName = "One through Five";
for( int i = 0; i < 5; ++i)
{
FileWriter << x[i] << ',';
}
FileWriter << dataName << std::endl;
FileWriter.close();
这当然很容易,但这似乎很俗气,实际上效率低下。我想知道是否有更好的方法来保存数据,并且在我以后去阅读数据时仍然可以将其分离。
不幸的是,我所做的搜索只产生了以下内容:
std::getline( FileReader, myStringBuffer, ',');
那么我是否可以存储单独的数据点,以便它们可以在读取时区分为单独的数据点,而无需在保存时使用分隔字符?也就是说,不用一些字符或空格分隔数据。
基本的二进制文件 io 实践将做你想要的。读取二进制数据时,您需要知道正在读取的每条数据的大小;了解这一点将推动您的许多设计决策。如果你想读取一个 int 后跟一个字符串,你需要知道一个 int 的大小(通过调用 sizeof(int)很容易找到),这样你就可以从你尝试加载数据的二进制 blob 中"蚕掉"一个 int 的数据,然后在你读取 int 的数据后,你需要知道你的字符串有多大。由于字符串的长度是可变的,你要么需要假设一个标准长度(哎呀!),要么先从已知大小的数据中读取长度,然后将这么多字节读入字符串。因此,数据编写器需要在写出字符串之前写出字符串(或任何其他可变大小的数据类型)的长度,作为已知的数据大小(例如将大小信息写入为无符号的整数)。
有关组织二进制数据以进行读取/写入的巧妙方法,请查看交换文件格式 (IFF)。这是TIFF,RIFF等的基础,并且是设计二进制文件blob的好方法。它基本上将数据存储为"块",其中数据首先写出一个块ID,然后是块的大小(以字节为单位),然后是该块的数据。这样,读取器程序可以检查块 ID,如果它不想/不知道如何处理某种甚至未知类型的数据,它可以跳过以字节为单位的块大小并读取下一个块。
按特定字符分隔值可以工作,具体取决于您的值:如果您的字符串不使用分隔字符,例如逗号,则可以使用逗号分隔符保存值。当没有已知是有用的分离字符时,事情就会变得有趣。在这种情况下,典型的方法是将引号与合适的转义字符一起使用,例如,C 和 C++ 用于特定字符串文字
:- 通常字符串以单引号开头
"
。 - 要将引号嵌入到字符串中,它通过反斜杠进行转义,例如
"""
. - 要嵌入转义字符反斜杠,它使用两个反斜杠,例如
"\"
.
有时使用的另一种方法是将值与大小前缀组合在一起。不过,使用什么取决于确切的需求。
当您使用逗号作为分隔符时,在读取格式化值(例如整数)时可能需要跳过逗号:它们不容易读取逗号,只是忽略它可能不合适。如果缺少,则显然是格式错误。您可能希望使用操纵器在存在时额外加一个逗号:
std::istream& comma(std::istream& in) {
std::istream::sentry cerberos(in);
if (in && in.peek() == ',') {
in.ignore();
}
else {
in.setstate(std::ios_base::failbit);
}
return in;
}
// ...
int i, j;
if (in >> i >> comma >> j) { ... }
输入表达式应读取两个逗号分隔的整数,如果任一值不是int
或它们未用逗号分隔,则失败。
正确理解您的问题,您希望知道如何以可以再次读取的格式存储数据(大概在另一个C++程序中)。
如果是这样,那么您可以通过多种方式执行此操作:
最常见(也是最简单的)方法是通过以下方式:
- 空格分隔(例如):
value1 value2 value3
- 逗号(这将生成一个逗号分隔的文件,通常称为 CSV 文件)
1,2,3
. - 或者,任何字符:
1#2#3
这样您就可以像以前一样使用std::getline
(例如,对于 CSV):
char delim = ',';
while(std::getline(input_stream, temporary_string, delim) {
//data handling goes here...
}
当然,由于这是一个幼稚的例子(即您的数据被结构化为表格),您必须调整代码以处理通常跨越多行的多方面数据,方法是读取数据块并根据格式解析这些块。
复杂示例(卫星坐标):
1.1 1.2 1.3 1.4 1.5
1.6 1.7 1.8 1.9
2.0
2.0
2.1 2.2 2.3 2.4 2.5
2.1 2.4
这是空格分隔的,具有以下格式:
- 每个数据点都以以下模式存储:数据、空间。
- 如果数据点不存在,则由空格表示,除非是最后一个不存在的数据点,其中所有其他输出都是截断为换行符。
- 如何在C++中读取空格分隔的输入 当我们不知道输入的数量时
- 如何将以逗号和空格分隔的整数读取到 2D 数组中?
- 如何逐行读取文件,每行中的内容都用空格分隔并将其写入新文件中
- 如何在 C++ 中将文件中的逗号分隔数字读取到数组中?
- 读取制表符分隔的文件时出现问题 C++
- 如何将逗号分隔的文件读取为 2D int 数组?
- 读取带有分隔C++的文件
- 嵌套结构,从由空行分隔的文件中读取数据
- 使用 range-v3 读取包含逗号分隔数据的行
- 如何从文件中读取用空格分隔的数字
- 从文件中读取后,将分号分隔的整数存储到数组中
- 如何逐行读取文件并分隔行组件?
- 如何在 c++ 中读取与反斜杠分隔的键对应的值
- 读取以逗号分隔的数字,并将其写入以制表符分隔的文件
- C++ 从文件中读取 int,每个数字用逗号分隔
- 将制表符分隔的值从文本文件读取到数组中
- C 如何读取具有逗号分隔的值的文件
- 使用 cin 读取逗号分隔的整数对 (x,y) 和任意空格
- C 程序要读取包含两个双重值的Excel数据的单列,这些值由逗号分隔并存储在自己的数组中
- 正在读取由换行符分隔的文本文件.unix上的C++