从文件中读取整数输入到动态数组中并打印它
Reading integer input from file into a dynamic array and printing it
我正在尝试编写一个程序,从输入文件中读取整数并输出动态数组。这个数组就是输入的大小。为了验证,我还想打印数组。输出将被传递给一个函数来创建一个排序的链表。
我尝试了以下操作,但没有成功:
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
我哪里做错了?
正如π α ντα ρ ε ν所指出的,我所提供的解决方案并不完全安全,这就是为什么我将提供第三个例子,使用boost::spirit。
参见快速修复和好的解决方案,以及π ντα ρ ε ε>的答案,使其在不使用boost的情况下工作。
我个人最喜欢的解决方案: 注意,这个例子确实需要将文本文件读入字符串。
#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 22n12 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文档中给出的示例构建的。
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;
关闭并重新打开流应该可以工作,但是还有更有效的解决方案…
好的解决方案:
例如,可以对动态增长的向量进行读取和插入操作。参考文档std::vector<int> dataArray;
while (input >> get)
{
dataArray.insert(dataArray.end(), get);
}
for(auto&& value : dataArray)
{
std::cout << value << std::endl;
}
这样做有很多好处:
- 在堆栈上分配向量可以防止强制调用delete。另一种选择是标准的智能指针。
- for每个循环即使不计算元素也能工作。如果你需要元素的数量,你可以直接询问vector的大小。
你的代码有几个误解和缺陷:
(1)应用此循环计算输入
while (input >> get)
count++;
输入流的状态是上次提取操作(input >> get
)失败后的结果。因此,如果不完全重置流,则无法读取进一步的输入。
(2)显示的第二个循环
for (int i = 0; i < count; i++) {
input >> array[i];
}
在无效状态下使用input
流(整个流已经被读取到input.eof()
),因此从它读取会导致'奇怪的值'(换句话说:此时未定义行为)。
我将编写下面经过验证的代码来解决这个
// 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
相关文章:
- 动态分配的聊天数组打印缺失的数据和空
- 对象数组打印空白字符串
- 数组打印"random"值时出现问题
- 数组打印出垃圾值
- 数组打印奇怪的字符,例如 ∟ @
- 测量我的随机数数组打印的时间始终显示为 0 秒
- 数组打印出错误的数字
- 从对象数组打印字符串对象
- 您好,如何防止此函数使用质数数组打印 1
- 如何从主内部的数组打印总计
- 如何将数组打印为矢量形式
- 有人能给我一些关于在C++中使用数组打印出丰富、完美和不足的数字的提示吗
- 为什么我的C++数组打印相同的值
- 如何阻止我的数组打印地址
- 将值输入到结构数组 + 打印输出
- C++11 为什么 cout 从布尔数组打印大整数
- 从字符串数组打印其中一个字符串时出现空指针赋值错误
- 将无符号字符数组打印为十六进制
- 缩短的数组打印错误的结果
- C++中的字符串数组:打印额外的字符