如何从文件读取特定数量的字符到结构

时间:2019-05-05 18:11:04

标签: c++

我需要从此数据文件中读取20个字符:

    7
    Petras A. Petraitis 120 15 20 0 
    Jurgis Jurgutis     222 16 12 22
    Rimas Jonas         138 15 15 59
    Bei Lin Sin Mun     23 15 0 0   
    Zigmas Nosis        256 16 23 9 
    Romas Senasis       111 15 15 15
    Jurgis Stasys Lydeka199 16 13 9 
    6
    256 16 43 15
    120 15 50 10
    111 16 5 35 
    199 16 35 59
    222 16 42 22
    23 15 30 0  

基本上每个字母和空格一直到数字。我尝试使用read(),但无法使其与struct一起使用。我也一直尝试使用getline(),但它对我也不起作用。我到处都在看,但是大多数教程都是通过直接用户输入而不是从文件中读取来显示的。

    #include <iostream>
    #include <fstream>
    #include <string>

    using namespace std;

    struct competition{
        string name; // athletes name
        int athleteNum; // number
        int startHours; // starting time: hours
        int startMin; // starting time: minutes
        int startSec; // starting time: seconds
    };

    int main()
    {
        ifstream duom ("U2.txt");

        competition athletes[30];
        int n; // amount of athletes
        duom >> n;
        for (int i=0; i<n; i++){
            duom.getline(athletes[i].name, 20);
        }
        return 0;
    }

使用getline()代码无法编译,因此我可能语法错误,并且read()似乎不适用于struct。

3 个答案:

答案 0 :(得分:0)

您几乎是正确的。 istream::getline()在第一个参数处等待char *,但是您正在传递std::string。请记住,如果getline没有读取符号到定界符(默认情况下为行尾,这取决于您的情况),它将为输入流(duom)设置故障位。您需要istream::clear()。另外,您正在混合duom >> n;和文件读取。也许您想从文件中读取结构信息,并从n中读取cin

更新

您需要使用istream::ignore()跳过换行符。同样,您的示例的名称在8行上有20个符号,但是istream::getline提取的名称比指定的少一个。以下代码不包含任何错误检查。

int main()
{
    ifstream duom("U2.txt");
    competition athletes[30];
    int n; // amount of athletes
    duom >> n;
    duom.ignore(1);

    char name[256];
    for (int i = 0; i < n; i++) {
        duom.getline(name, 21);
        if (duom.fail())
            duom.clear();
        athletes[i].name = name;
        duom >> athletes[i].athleteNum >> 
                athletes[i].startHours >> 
                athletes[i].startMin >> 
                athletes[i].startSec;
        duom.ignore(1);
    }
    return 0;
}

如果您不想阅读其他运动员成员,也应该用istream::ignore()跳过他们,而不是用duom >> ...阅读:

duom.ignore(32); // skip up to 32 characters or '\n' 

https://en.cppreference.com/w/cpp/io/basic_istream/ignore

答案 1 :(得分:0)

正如alezh所指出的,istream::getline()char*而不是std::string。您可以创建一个char hold[50]变量以传递给istream::getline()duom.getline(hold, 50);,然后将std::string分配给该变量:athletes[i].name = std::string(hold, 20);

正如他指出的那样,duom >> n;不会使您进入下一行。您可能希望在该行之后duom.ignore(20, '\n')从正确的行开始。或者不首先将>>getline一起使用。

嵌套for循环的作用是什么?您可以摆脱第二行for

答案 2 :(得分:0)

据我在文件组织和处理过程中的知识..每个文件记录应具有定义的结构,例如:固定长度字段和记录或具有固定记录大小的可变长度字段...等

所以..您必须先定义文件的结构才能读取它。我认为上面的这些记录没有定义的结构,因此您无法读取它。

但是通常使用函数file.read()/file.write()比使用运算符<< / >>更好,  因为在它们中,您可以通过将对象写入char数组中(定义其属性并将其添加到其中),然后将数组写入文件中,从而很好地定义文件的结构。

您可以通过读取动态char []来逐条记录地读取记录,然后使用istrstream对象通过getline函数将其属性分开,直到它到达变量号为止(如果它是可变字段,或者是固定大小的字段,并且记录你只能说file.read((char *)&object_name,sizeof(object))

例如,运算符“ >>”输入变量,直到到达空格..,并且getline读取直到找到定界符(默认定界符为endl)。 那么,如何从文件中读取字符串?我认为您无法读取该文件,因为它的记录没有特定的结构。