我正在尝试编写一个从输入文件中读取整数并输出动态数组的程序。此数组将是输入的大小。为了验证,我还想打印阵列。输出将传递给函数以创建已排序的链接列表。
我尝试了以下操作,但它不起作用:
istringstream input(R"inp(
23 43 12 67
18 15 22
12 xxx 23 12 xx 34556 11 11 www
)inp");
int get, count = 0;
while (input >> get)
count++;
cout << "Number of integers: " << count << endl;
int *array = new int [count];
for (int i = 0; i < count; i++)
{
input >> array[i];
}
for (int i = 0; i < count; i++)
{
cout << *(array+i) << endl;
}
delete[] array;
问题是输出显示了一些奇怪的数字,与输入完全无关:
整数:8
-1217944384
-1217944384
-1
538976266个
540226080个
824193844
我哪里出错了?
答案 0 :(得分:1)
正如πάνταῥεῖ指出的那样,我提供的解决方案并不完全安全,这就是为什么我将使用boost::spirit提供第三个例子。
查看点快速修复和良好解决方案,以及πάνταῥεῖ的答案,让它在不使用提升的情况下运行。
我个人最喜欢的解决方案: 请注意,此示例确实需要将文本文件读取为字符串。
#include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
template<typename Iterator>
bool
parse_numbers(Iterator first, Iterator last, std::vector<int>& v)
{
bool r =
boost::spirit::qi::parse(first, last,
// Begin grammar
(boost::spirit::qi::int_[boost::phoenix::push_back(
boost::phoenix::ref(v), _1)]
% *(boost::spirit::qi::char_("a-zA-Z")
| boost::spirit::ascii::space)));
if (first != last) // fail if we did not get a full match
return false;
return r;
}
const std::string s = "23 43 12 67 \n18 15 22\n12 xxx 23 12 xx 34556 11 11 www";
std::string::const_iterator start = s.begin(), stop = s.end();
std::vector<int> results;
parse_numbers(start, stop, results)));
for(int i : results)
std::cout << value << ' ';
结果将如预期的那样:
23 43 12 67 18 15 22 12 23 12 34556 11 11
上面的示例部分建立在boost :: spirit文档中的example given。
input >> get
移动当前的光标位置,因此在您的while循环之后,您无需阅读任何内容。
快速修复:
ifstream input;
input.open("file.txt");
int get, count = 0;
while (input >> get)
count++;
input.close();
input.open("file.txt");
int *array = new int [count];
for (int i = 0; i < count; i++)
{
input >> array[i];
}
for (int i = 0; i < count; i++)
{
cout << *(array+i) << endl;
}
input.close();
delete[] array;
关闭并重新打开流应该有效,但有更有效的解决方案......
良好的解决方案:
例如,可以是读取并插入到动态增长的向量中。有关详细信息,请参阅the documentation。std::vector<int> dataArray;
while (input >> get)
{
dataArray.insert(dataArray.end(), get);
}
for(auto&& value : dataArray)
{
std::cout << value << std::endl;
}
这将有多重优势:
答案 1 :(得分:1)
您的代码有几个误解和缺陷:
(1)应用此循环后计算输入
while (input >> get)
count++;
输入流的状态留在失败的最后一次提取操作(input >> get
)的结果上。因此,如果不完全重置流,则无法读取其他输入。
(2)你正在展示的第二个循环
for (int i = 0; i < count; i++) {
input >> array[i];
}
使用处于无效状态的input
流(整个流已经读取到input.eof()
),因此从中读取会导致'奇怪的值'(在其他情况下)单词:此时 未定义的行为 。)
我会写following proven code来解决这个问题
// Your literal input file formatting goes here
istringstream input(R"inp(
23 43 12 67
18 15 22
12 xxx 23 12 xx 34556 11 11 www
)inp");
int current;
vector<int> allIntInputs;
while (input >> current || !input.eof()) {
if(input.fail()) {
input.clear();
string crap;
input >> crap; // read anything up to the next
// whitespace delimiter (the default deleimiters)
continue; // with the next item
}
// Everything's fine we'll add another number
allIntInputs.push_back(current);
}
// Print all integer values extracted
cout << "Integer values read from input:" << endl;
for(vector<int>::iterator it = allIntInputs.begin();
it != allIntInputs.end();
++it) {
if(it != allIntInputs.begin()) {
cout << ' ';
}
cout << *it;
}
cout << endl;
输出
Integer values read from input:
23 43 12 67 18 15 22 12 23 12 34556 11 11