尝试使用c ++ getline函数进行格式化。输出将所有内容放在第一个记录编号的姓氏上,而不是应放在的位置。
代码:
#include <fstream>
#include <string>
#include <iostream>
using namespace std;
int main()
{
const int RANGE = 12;
string tab[RANGE];
int i = 0, j = 0;
ifstream reader("records.txt");
if (!reader)
{
cout << "Error opening input file" << endl;
return -1;
}
while (!reader.eof())
{
if ( ( i + 1) % 4 == 0)
getline( reader, tab[i++], '\n');
else
getline( reader, tab[i++], '\t');
}
reader.close();
i = 0;
while (i < RANGE)
{
cout << endl << "Record Number: " << ++j << endl;
cout << "Forename: " << tab[i++] << endl;
cout << "Surname: " << tab[i++] << endl;
cout << "Department: " << tab[i++] << endl;
cout << "Telephone: " << tab[i++] << endl;
}
return 0;
}
TXT文件的内容:
John Smith Sales 555-1234
Mary Jones Wages 555-9876
Paul Harris Accts 555-4321
请自己运行代码以了解会发生什么,然后将txt文件与代码放在同一文件夹中。
希望有人可以帮我谢谢。
答案 0 :(得分:1)
请参见Why is iostream::eof inside a loop condition (i.e. while (!stream.eof())) considered wrong?。
另外,如果文件少于12个字符串,最后的 .modal-content {
width: 1200px
}
.modal-dialog {
margin-left: 285px !important
}
@media screen and (max-width: 1000px) {
.modal-dialog {
margin-left: 100px !important
}
}
循环应仅输出实际读入数组的字符串,而不是完整数组的字符串。但是除非您可以保证文件不超过12个字符串,否则应使用while
而不是固定数组。
此外,我不会在单个循环中交替使用std::vector
分隔符,而是仅使用外部循环读取整行,然后从每一行分别读取制表符分隔的值。然后将值存储在struct的数组/向量中,而不是单独存储。
尝试更多类似的方法:
getline()
答案 1 :(得分:0)
在istream中有更简单的方法来分隔单词,即C ++ sring流工具:
#include <fstream>
#include <iostream>
#include <sstream> //<-- string stream library
using namespace std; //<-- should not be used, use scope std::
int main() {
const int RANGE = 12;
string tab[RANGE];
string temp; //<--to store each field temporarily
int i = 0, j = 0;
ifstream reader("records.txt");
if (!reader) {
cout << "Error opening input file" << endl;
return -1;
}
while (getline(reader, temp)) { //<-- read one full line
stringstream ss(temp); // <-- input to a string stream
while(ss >> tab[i]){ // <-- passing strings to the string array one by one
i++;
}
}
reader.close();
i = 0;
while (i < RANGE) {
cout << endl << "Record Number: " << ++j << endl;
cout << "Forename: " << tab[i++] << endl;
cout << "Surname: " << tab[i++] << endl;
cout << "Department: " << tab[i++] << endl;
cout << "Telephone: " << tab[i++] << endl;
}
return 0;
}
这里的想法是尽可能减少代码混乱,我建议的一件事是使用std::vector
而不是常规的固定大小数组。另外,正如所说的和链接的那样,eof
是非常不可靠的。
答案 2 :(得分:0)
我认为,问题的根源在Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?中得到了解释。
由于该错误,您正在读new_file_name = old_file_name.replace(^[A-Za-z0-9_.]+$, '');
,tab[12]
,tab[13]
和tab[13]
。当然,这会导致不确定的行为。
将循环更改为:
tab[14]
请确保添加
// Read the contents of the file line by line
std::string line;
while (getline( reader, line))
{
// Process each line's contents.
std::istringstream str(line);
getline(str, tab[i++], '\t');
getline(str, tab[i++], '\t');
getline(str, tab[i++], '\t');
getline(str, tab[i++], '\n');
}
要确保没有使用超出范围的索引,请添加检查。
#include <sstream>
答案 3 :(得分:0)
首先,while (!reader.eof())
is not doing the right thing。
您看到的直接问题是由于文件不包含'\t'
,因此,第一个getline
已经将文件的所有内容读入tab[0]
。 (至少那是我一对一复制文件内容后得到的东西)
您的代码相当困难,因为在使用变量之前要先声明它们,然后再使用它们。您具有固定大小的数组,但是当文件中有更多行时,代码将崩溃。同样,将所有内容读入简单的字符串数组会使事情变得复杂。访问forename
或其他字段需要您计算数组中的偏移量。更好地使用数据结构:
struct file_entry {
std::string first_name;
std::string last_name;
std::string departure;
std::string phone;
};
然后您可以定义输入运算符:
std::istream& operator>>(std::istream& in,file_entry& fe) {
return in >> fe.first_name >> fe.last_name >> fe.departure >> fe.phone;
};
并使用std::vector
存储与文件中一样多的条目:
int main() {
std::string contents{"John Smith Sales 555-1234\n"
"Mary Jones Wages 555-9876\n"
"Paul Harris Accts 555-4321\n"};
std::stringstream reader{contents};
std::vector<file_entry> data;
std::string line;
while (std::getline(reader,line)) {
file_entry fe;
std::stringstream{line} >> fe;
data.push_back(fe);
}
for (const auto& fe : data) {
std::cout << "Forename: " << fe.first_name << '\n';
std::cout << "Surname: " << fe.last_name << '\n';
std::cout << "Department: " << fe.departure << '\n';
std::cout << "Telephone: " << fe.phone << '\n';
}
}
PS ,您无需在文件上调用close
,这已经在其析构函数中完成了。不显式调用它的好处是,适用于文件流的相同代码也适用于字符串流。