谁能告诉我我用getline

时间:2020-01-30 21:27:27

标签: c++ format getline

尝试使用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文件与代码放在同一文件夹中。

希望有人可以帮我谢谢。

4 个答案:

答案 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';
    }
}

live example

PS ,您无需在文件上调用close,这已经在其析构函数中完成了。不显式调用它的好处是,适用于文件流的相同代码也适用于字符串流。