从输入文件中获取字符串直到整数?C++
Get string from input file until integer? C++
我的一个输入文件,看起来像这样:
Stroustrup, Bjarne 8 8 -1 -1 -1
Lovelace, Ada 1 60 14 43 -1
von Neumann, Jon 77 48 65 -1 -1
Wirth, Niklaus 51 59 -1 -1 -1
Wozniak, Steve 81 -1 -1 -1 -1
Babbage, Charles 31 92 -1 -1 -1
Hopper, Grace 76 -1 -1 -1 -1
Bird, Tweety -99 -99 -99 -99 -99
Sylvester 77 39 -1 -1 -1
我当前的程序使用流式传输数据
infile >> lastName >> firstName >> ...
不幸的是,这只适用于其他输入文件,因为每一行实际上都有姓氏和名字。这里,由于第三行中有两个部分的姓氏,而最后一行中只有名字,所以其余数据无法流式传输。有没有什么方法可以从一行的开头抓取一个字符串,直到它达到一个整数?
在解析输入文件时,您几乎永远不会得到直接使用原始流来用值填充变量的解决方案。输入格式可能不同,可能出现错误。。。在这种情况下,更好的方法是逐行读取输入并分别处理每一行。在处理每一行时,您可以构建一个临时istringstream
,用于从中读取单词,并检查单词是否可以转换为数字(如果0
不是有效值,请使用std::atoi
):
std::string line;
while (std::getline(infile,line))
{
if (line.empty()) continue;
std::istringstream is(line);
std::string word;
while (is >> word)
{
int val = std::atoi(word);
if (val)
{
// TODO: number
}
else
{
// word
}
}
}
或者,您可以考虑使用std::isdigit
来检查单词的第一个字符是否为数字:
if (std::isdigit(word[0])) ...
您可以控制输入文件的格式吗?鉴于您既可以选择由两部分组成的名称(例如"von Neumann"),也可以选择由一个名称(例如,不是第一个和最后一个,例如"Sylvester"),解析起来会变得不必要的困难。若你们可以引用名称,比如"von Neumann", Jon
,那个么事情可能会容易得多。
一种方法可能包括:
#define DELIM 'c'
ostringstream namestream;
infile.get(namestream, DELIM);
string name = namestream.str();
这将从中野获得字符串,直到到达字符DELIM。查看您的文件,它看起来像是名称部分和名字/姓氏由空格或逗号后跟空格分隔,其中名称末尾和第一个数字之间的间隙可能是一个制表符。如果是这种情况,您可以使用制表符('t'
)作为delimeter字符。
不幸的是,这种方法只支持将DELIM作为单个字符,而不是一组字符。因此,您将无法读取第一个数字(如果您想支持负数,则无法读取"digiit或'-'")。
下面是一个完整的示例程序:
#include <iostream>
#include <string>
#include <locale>
#include <fstream>
template<
class charT,
class iter_type,
class string_iterator_type
>
void basic_get_name(iter_type beg, iter_type end, std::ios_base& str,
string_iterator_type it1, string_iterator_type it2)
{
auto ctypeFacet = &std::use_facet<std::ctype<charT>>(str.getloc());
typedef std::ctype_base base_type;
while (beg != end)
{
if (ctypeFacet->is(base_type::alpha | base_type::punct, *beg))
*it1++ = *beg;
else if (ctypeFacet->is(base_type::space, *beg))
{
if (ctypeFacet->is(base_type::alpha, *++beg))
{
while (ctypeFacet->is(base_type::alpha, *beg) && (beg != end))
*it2++ = *beg++;
break;
}
break;
}
++beg;
}
}
template<class charT>
void get_name(std::basic_istream<charT>& is, std::basic_string<charT>& first,
std::basic_string<charT>& last)
{
typedef std::istreambuf_iterator<charT> iter_type;
basic_get_name<charT>(iter_type{is}, iter_type{},
is, std::back_inserter(first),
std::back_inserter(last));
}
以下是您的称呼:
int main()
{
std::string first, last;
get_name(infile, first, last);
std::cout << first << last;
}
您甚至可以创建自己的同时具有名字字符串和姓氏字符串的类,并创建一个用于将名称提取到这些数据成员中的方面。
并且get_name
应该返回流,以便可以对流状态进行检查。目前,这段代码并没有做到这一点,但它可以通过类型为ios_base::iostate
的参数来实现,并在basic_get_name
中向其添加流状态错误位。
- 如何反转整数参数包
- enum是C++中的宏变量还是整数变量
- 努力将整数转换为链表。不知道我在这里做错了什么
- 整数不会重复超过随机数
- 在C++中手动调整数组大小
- 检查输入是否不是整数或数字
- C++使用整数的压缩数组初始化对象
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 将"打开的CV图像"中的"颜色"转换为整数格式
- 通过套接字[TCP]传输数据 如何在C / C ++中打包多个整数并使用send() recv()传输数据
- 如何只允许用户输入正整数
- 如何在c++中从文本文件中逐行读取整数
- C++:如何循环通过向量中的整数元素
- 我可以信任表示整数的浮点或双精度来保持精度吗
- 序列化,没有库的整数,得到奇怪的结果
- 在一定长度后从数组中打印时缺少整数
- std::当在256字节边界上写入整数时,流的奇怪行为
- 内联程序集printf将整数解释为地址
- 是否基于数组B整数打印数组A中的整数
- 如何在C++中将整数转换为其数字数组