c++ - 如何从两个分隔符之间的文件中提取数据或读取数据--> '|' 在 C++ 中使用 getline 函数?
问题描述
我已经在文件中的分隔符之间安排了数据。我想在一行中从一个特定点读取到另一个点。它看起来像这样:| 没有。姓名。| 产品。| 价格。| 我想一次读取一个数据。由这些分隔符划分的每个部分都包含一个或多个音节,即一个或几个单词。我怎么读这个?
解决方案
分隔文件的基本方法是将整行读入 a ,然后从该行string
创建 a并循环使用分隔符(此处)调用 stringstream 以将值分隔到字段中。stringstream
getline
'|'
(这种方式不需要提前知道字段的数量——没有stringstream
你必须限制你对字段的读取到使用的数量,getline
或者很getline
乐意从下一行开始读取数据)
下面的示例只是将输入文件的每个字段读入 a string
,但根据您的需要,您可能需要额外的转换,(例如stol
等)将各个字段转换为int
or double
(留给您)。
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <limits>
using namespace std;
int main (int argc, char **argv) {
string line;
if (argc < 2) {
cerr << "error: usage, program <filename>\n";
return 1;
}
ifstream f (argv[1]); /* open file */
if (!f.is_open()) { /* validate file open for reading */
perror (("error while opening file " + string(argv[1])).c_str());
return 1;
}
while (getline (f, line)) { /* read each line */
string val; /* string to hold value */
stringstream s (line); /* stringstream to parse fields */
/* output original line */
cout << "line: " << line << "\n\n";
/* skip 1st delim */
s.ignore(numeric_limits<streamsize>::max(), '|');
while (getline (s, val, '|')) /* for each field */
cout << " value: " << val << '\n'; /* output each field value */
cout << '\n';
}
}
示例输入文件
$ cat dat/fields.txt
| 1 | Joe | marbles | 1.25 |
| 2 | Mike | jacks | 13.49 |
| 3 | Jill | pail | 4.50 |
示例使用/输出
$ ./bin/iostream_strstream_fields dat/fields.txt
line: | 1 | Joe | marbles | 1.25 |
value: 1
value: Joe
value: marbles
value: 1.25
line: | 2 | Mike | jacks | 13.49 |
value: 2
value: Mike
value: jacks
value: 13.49
line: | 3 | Jill | pail | 4.50 |
value: 3
value: Jill
value: pail
value: 4.50
如果您还有其他问题,请仔细查看并告诉我。
用 C 重写 32 年的操作系统
由于您试图在一个 32 岁的操作系统上使用仍然无法识别的 C++ 编译器进行编译(在您的原始问题中没有指定任何一个),您可能会更好地使用 C 编写您的解析例程。为什么?C++ 标准在当时是非常无定形的。与今天的 C++ 相比,它更像是 C 的超集。在当时的 Turbo C 和 Borland C++ 编译器中,所有包含的文件仍然使用 C 头文件包含格式(其中包含头文件'.h'
名称的末尾,例如#include <string.h>
)这解释了您的“找不到头文件”问题。
另一方面,C 更接近于今天可用的。虽然它经过了几次标准修订,但当时和现在可用的基本功能是相同的。在 C++ 代码上运行 DOS 3.2 的任何内容上,以下代码都有更好的机会进行编译。
#include <stdio.h>
#include <string.h>
#define FLDSZ 32 /* maximum file size for name and product */
#define MAXC 256 /* maximum length for line (including '\0') */
int main (int argc, char **argv) {
char buf[MAXC] = ""; /* buffer to hold each line */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) { /* validate file open for reading */
fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
return 1;
}
while (fgets (buf, MAXC, fp)) {
int id; /* id from file */
char name[FLDSZ] = "", /* name */
product[FLDSZ] = ""; /* product */
float price; /* price */
size_t len = strlen (buf); /* length of string in buffer */
if (len == MAXC - 1 && buf[len - 1] != '\n') { /* check it fit */
fputs ("error: line too long.\n", stderr);
return 1;
}
if (sscanf (buf, "|%d | %31s | %31s | %f", /* parse fields */
&id, name, product, &price) != 4) {
fputs ("error: failed to parse line.\n", stderr);
continue;
}
/* output parsed fields */
printf ("%3d %-10s %-10s %.2f\n", id, name, product, price);
}
if (fp != stdin) fclose (fp); /* close file if not stdin */
return 0;
}
stdin
(程序期望数据文件名作为第一个参数,或者如果没有给出参数,它将读取)
示例使用/输出
$ ./bin/fieldparse ~/dev/src-cpp/tmp/dat/fields.txt
1 Joe marbles 1.25
2 Mike jacks 13.49
3 Jill pail 4.50
我能告诉你的就是试一试,让我知道会发生什么。
推荐阅读
- android - 无法弄清楚如何将此字段保存到数据库中。我已经编写了数据类、dao 和类型转换器,但仍然无法检测到错误
- composer-php - Laravel 8 安装程序错误——“--remove-vcs”选项不存在
- javascript - 尝试在网页中显示酒店数据的 Amadeus Test Api 时出错
- amazon-web-services - 是否可以覆盖 AWS SAM 策略模板占位符变量
- python - 没有换行符的数字字符串的正则表达式
- java - 想从 Docker 运行 mysql 并用 springboot 连接
- php - 如何将图像发送到 Laravel 8 中的 Stripe Checkout Session
- c - C 函数 printf 中格式说明符的手册页在哪里?
- c - 确定 C 中字符串输入的内存分配大小(scanf)
- swiftui - 为什么我的 AVVideoCapturePreview 不在图层中渲染?