用read()读不到“大”结构

时间:2018-06-03 00:16:02

标签: c++

我有一个结构,想要写信息,然后得到一个。

struct st
{
    char something[21];
    char something2[21];
    ...
}

void input (st &data)
{
    ...
    std::fstream fl(filename, std::ios::out);
    ...
    while(...)
    {
        std::cout << "Enter sth: ";
        std::cin >> data.something;
        ...
        fl.write ((char*) &data, sizeof(data));
    }
    fl.close();
}

void output (st &data)
{
    ...
    std::fstream fl(filename, std::ios::out | std::ios::in);
    ...
    fl.read ((char*) &data, sizeof(data));
    while (!fl.eof())
    {
        std::cout << data.something << std::endl;
        ...
        fl.read ((char*) &data, sizeof(data));
    }
    ...
    fl.close();
}

在示例中,我在struct中有两个元素,它的大小一起是42个字节。当我添加更多变量时,它的大小将是165个字节,我仍然可以在colsole上看到文件中的内容,但是当它的大小超过165个字节时,我什么都看不见。 当我进入调试模式时,我发现了

output()

循环while(!fl.eof())中的函数没有入口。

我无法理解为什么函数read()不会从文件中读取数据。 我从一个exapmle中取出了这个代码并将一个插入我的:

std::cout << "Reading " << sizeof(data) << " characters... ";
fl.read ((char*) &data, sizeof(data));

if (fl)
    std::cout << "all characters read successfully.";
else
    std::cout << "error: only " << fl.gcount() << " could be read.";

我跑了然后得到:

Reading 216 characters... error: only 52 could be read.

为什么呢?输入是正确的。输入信息时我没有超过char数组大小。

编辑。我添加了完整的代码...... 这是完整的代码。

#include <fstream>
#include <iostream>
#include <cstdlib>
#include <iomanip>
#include <windows.h>
#include <conio.h>
#include <iterator>

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
struct st_general
{
    struct
    {
        char name[21];
        char surname[21];
        char patronym[21];
        char group[9];
        char sex[2];
        char book_num[7];
        char birth_date[9];     // DD.MM.YY
    }main;

    struct
    {
        char town[21];
        char district[21];
        char street[21];
        char built_num[7];
    }loc;
/**
    struct
    {
        char phone_num_1[11];
        char phone_num_2[11];
    }cont;
*/
};

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename T>
void normalize (std::string sent, T &value) // link(?) to a value
{
    std::cout << sent;
    std::cin.getline(value, sizeof(value));
    *std::prev(std::end(value)) = '\0';
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void input_inf (st_general &data)
{
    char *filename = "little_snake.txt";

    int clean;
    std::cout << "Clean the file? 0 - No, otherwise - Yes: ";
    std::cin >> clean;

    std::fstream fl(filename, (clean ? (std::ios::out) : (std::ios::out | std::ios::app)));

    if (!fl)
    {
        std::cerr << "ERROR::WRITING::UNABLE::TO::CREATE::OR::OPEN::FILE";
        exit(true);
    }

    int want;
    std::cout << "Enter information? 0 - No, otherwise - Yes: ";
    std::cin >> want;

    std::cin.get();

    // Enter information into the file
    while (want)
    {
        normalize ("Enter name: ", data.main.name);
        normalize ("Enter surname: ", data.main.surname);
        normalize ("Enter patronym: ", data.main.patronym);
        normalize ("Enter group: ", data.main.group);
        normalize ("Enter sex (M, F): ", data.main.sex);
        normalize ("Enter book number: ", data.main.book_num);
        normalize ("Enter birth date: ", data.main.birth_date);

        normalize ("Enter town: ", data.loc.town);
        normalize ("Enter district: ", data.loc.district);
        normalize ("Enter street: ", data.loc.street);
        normalize ("Enter built number: ", data.loc.built_num);
/**
        normalize ("Enter phone number 1: ", data.cont.phone_num_1);
        normalize ("Enter phone number 2: ", data.cont.phone_num_2);
*/
        fl.write((char*) &data, sizeof(data));
        std::cout << "Input 0 to cancel: ";
        std::cin >> want;
    }

    fl.close();
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void output_inf(st_general &data)
{
    char *filename = "little_snake.txt";
    std::fstream fl(filename, std::ios::out | std::ios::in);

    if (!fl)
    {
        std::cerr << "ERROR::READING::UNABLE::TO::OPEN::FILE";
        exit(true);
    }
    std::cout << " ______________________ ______________________ ______________________ __________ ___ ________ __________ ______________________ ______________________ ______________________ ________ ____________ ____________\n"
              << "|         Name         |       Surname        |       Patronym       |  group   | S | book_n |  birth   |         town         |       district       |        street        | built  |   phone    |   phone    |\n"
              << "|______________________|______________________|______________________|__________|___|________|__________|______________________|______________________|______________________|________|____________|____________|\n";

    std::cout << "Reading " << sizeof(data) << " characters... ";
    fl.read ((char*) &data, sizeof(data));

    if (fl)
        std::cout << "all characters read successfully.\n";
    else
        std::cout << "error: only " << fl.gcount() << " could be read.\n";

    // reading from the file
    while (!fl.eof())
    {
        std::cout << "|"
                  << std::setw(21) << data.main.name         << " |"
                  << std::setw(21) << data.main.surname      << " |"
                  << std::setw(21) << data.main.patronym     << " |"
                  << std::setw(9)  << data.main.group        << " |"
                  << std::setw(2)  << data.main.sex          << " |"
                  << std::setw(7)  << data.main.book_num     << " |"
                  << std::setw(9)  << data.main.birth_date   << " |"

                  << std::setw(21) << data.loc.town          << " |"
                  << std::setw(21) << data.loc.district      << " |"
                  << std::setw(21) << data.loc.street        << " |"
                  << std::setw(7)  << data.loc.built_num     << " |"
/**
                  << std::setw(11) << data.cont.phone_num_1  << " |"
                  << std::setw(11) << data.cont.phone_num_2  << " |"
*/
                  << std::endl
                  << "|______________________|______________________|______________________|__________|___|________|__________|______________________|______________________|______________________|________|____________|____________|\n";

        fl.read ((char*) &data, sizeof(data));
    }

    fl.close();
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int main ()
{
//    system("chcp 1251>null");   // to support Russian language
    st_general cs17;

    input_inf (cs17);
    output_inf (cs17);

    _getch();

    return 0;
}

现在,如果您在结构,输入和输出函数中取消注释部分代码并尝试写入然后从中读取将会出错。不超过165个字节...

1 个答案:

答案 0 :(得分:-2)

解决方案是一个有趣的解决方案。至少截至目前我无法找到更好的东西。 有人注意到,当您几乎填充一组字符时,会成功读取此信息。所以,我创建了一个函数。这个添加&#39; \ 0&#39;如果您输入的符号多于数组可以包含的符号,则输入符号或剪切它。

之后读取所有字符都没有任何问题。

谢谢大家:))。