Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/157.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么';信息[]和#x27;提供错误的结构记录的名称?_C++_Arrays_Class_For Loop - Fatal编程技术网

C++ 为什么';信息[]和#x27;提供错误的结构记录的名称?

C++ 为什么';信息[]和#x27;提供错误的结构记录的名称?,c++,arrays,class,for-loop,C++,Arrays,Class,For Loop,该程序使用类并从文件中获取员工信息。我也提到了下面的文件。我还提到了我收到的输出,尽管有错误。输出中也有一些错误,但我认为这是因为它得到的信息错误 运行此程序时,我收到以下错误消息: Error: Run-Time Check Failure #2 - Stack around the variable 'info' was corrupted. 还有一条信息: Unhandled exception at 0x00950A89 in employee.exe: Stack cookie in

该程序使用类并从文件中获取员工信息。我也提到了下面的文件。我还提到了我收到的输出,尽管有错误。输出中也有一些错误,但我认为这是因为它得到的信息错误

运行此程序时,我收到以下错误消息:

Error: Run-Time Check Failure #2 - Stack around the variable 'info' was corrupted.
还有一条信息:

Unhandled exception at 0x00950A89 in employee.exe: Stack cookie instrumentation code detected a stack-based buffer overrun.
//此程序使用的文件为:

A.Smith                       20001 25 40
T.Philip                      20002 20 35
S.LOng                        20003 15 50
G.Santos                      20004 30 30
F.Farkas                      20005 22 55
//即使出现错误,运行后的输出仍为:

 This week's employee history

 Name           Id            Rate          Hours
*  A.Smith     20001         $25/h        40h
* T.Philip     20002         $20/h        35h
*   S.LOng     20003         $15/h        50h
* G.Santos     20004         $30/h        30h
* F.Farkas     20005         $22/h        55h


This week's payment

 Name               Payment
* ╠╠╠╠╠╠╠╠         $0        <----------There is this error too
*  T.Philip         $700
*    S.LOng         $825
*  G.Santos         $900
*   A.Smith         $1000


* The average wages of the employees: $685.00
本周的员工历史记录
姓名Id费率小时数
*A.史密斯20001美元/小时40小时
*T.Philip 20002美元/小时35小时
*S.LOng 20003美元/小时50小时
*G.桑托斯20004美元/小时30小时
*F.法卡斯20005美元/小时55小时
本周的付款
姓名付款

* ╠╠╠╠╠╠╠╠ $0很难找到碎片代码的所有潜在问题,但最好使用
std::string
s而不是
char[]
。它们更安全,还具有许多内置功能。他们也与misc合作得很好。STL中的函数

您的
struct记录信息[n]将仅保存
n
(5)个元素。如果您想向文件中添加更多条目,请使用标准容器,如std::vector

读取和写入文件通常可以使用自定义流操作符来完成,处理大量记录所需的所有免费函数都可以收集在自己的类中。我制作了一个
record
struct和一个
Records
类来演示如何将它们一起使用

#include <iostream>
#include <vector>
#include <iomanip>
#include <sstream>
#include <fstream>
#include <numeric>
#include <algorithm>
#include <functional>

struct record {
    std::string name{};
    std::string id{};
    int rate = 0;
    int hours = 0;
    int pay = 0;

    // stream operators for reading/writing a record
    friend std::istream& operator>>(std::istream&, record&);
    friend std::ofstream& operator<<(std::ofstream&, const record&);
    friend std::ostream& operator<<(std::ostream&, const record&);
};

// populate a record from an istream
std::istream& operator>>(std::istream& is, record& r) {
    std::string line;
    // get a line and check that it's > 30 chars long
    if(std::getline(is, line) && line.size()>30) {
        // extract the name and remove trailing spaces
        r.name = line.substr(0, 30);
        auto pos = r.name.find_last_not_of(' ');
        if(pos != std::string::npos)
            r.name = r.name.substr(0, pos+1);

        // put the rest of the line in a stringstream
        std::stringstream ss(line.substr(30));
        // and extract the rest of the fields
        if(ss >> r.id >> r.rate >> r.hours) {
            // calculate pay
            r.pay = r.rate * r.hours;
        } else { // if extraction fails, set the stream in fail mode
            is.setstate(std::ios_base::failbit);
        }
    } else is.setstate(std::ios_base::failbit);

    return is;
}

// streaming a record to an ofstream (like a file)
std::ofstream& operator<<(std::ofstream& os, const record& r) {
    os << std::setw(30) << std::left << r.name.substr(0, 30) << r.id << " " << r.rate << " " << r.hours << "\n";
    return os;
}

// streaming a record to a generic ostream (like std::cout)
std::ostream& operator<<(std::ostream& os, const record& r) {
    os << "* " << std::setw(30) << std::left << r.name << std::right << r.id
       << " $" << r.rate << "/h " << r.hours << "h $" << std::setw(4) << r.pay;
    return os;
}

class Records { // a class to maintain a number of "record"s
    std::vector<record> m_records{}; // stores all "record"s
public:
    Records(const std::string& filename) {
        record tmp;
        std::ifstream e(filename); // open file
        // and extract one record at a time and put it in m_records.
        while(e>>tmp) m_records.emplace_back(std::move(tmp));
    }

    // sum on any member in "record"
    template <typename field>
    auto Sum(field f) const {
        return std::accumulate(m_records.begin(), m_records.end(), 0,
                    [&](int a, const record& b) { return a + (b.*f); });
    }

    // average of any member in "record"
    template <typename field>
    auto Average(field f) const {
        return static_cast<double>(Sum(f)) / m_records.size();
    }

    // sorting on any member in "record"
    template <typename field, typename T>
    void Sort(field f, const T& cmp) {
        std::sort(m_records.begin(), m_records.end(),
                [&](const record& a, const record& b){ return cmp(a.*f, b.*f); });
    }

    // return the number of "record" elements
    std::vector<record>::size_type size() const { return m_records.size(); }

    // access an element via subscript
    record& operator[](std::vector<record>::size_type idx) { return m_records[idx]; }
    const record& operator[](std::vector<record>::size_type idx) const { return m_records[idx]; }

    // iterators to use in for-loops
    std::vector<record>::const_iterator cbegin() const noexcept { return m_records.cbegin(); }
    std::vector<record>::const_iterator cend() const noexcept { return m_records.cend(); }
    std::vector<record>::const_iterator begin() const noexcept { return cbegin(); }
    std::vector<record>::const_iterator end() const noexcept { return cend(); }
    std::vector<record>::iterator begin() noexcept { return m_records.begin(); }
    std::vector<record>::iterator end() noexcept { return m_records.end(); }

    // stream operator to show all records
    friend std::ostream& operator<<(std::ostream&, const Records&);
};

std::ostream& operator<<(std::ostream& os, const Records& R) {
    os << "  Name                            Id  Rate  Hrs  Pay\n";
    for(const auto& r : R) std::cout << r << "\n";

    os << std::setprecision(2) << std::fixed;
    os << "Average pay         : $" << std::setw(7) << R.Average(&record::pay) << "\n";
    os << "        rate        : $" << std::setw(7) << R.Average(&record::rate) << "\n";
    os << "        hours worked:  " << std::setw(7) << R.Average(&record::hours) << "h\n";
    return os;
}

int main() {
    // create a "Records" entity called "info" by reading a file
    Records info("Project 3.dat");

    // misc sorting and showing the result
    std::cout << "Sorted as read from the file:\n";
    std::cout << info;

    std::cout << "\nSorted according to name:\n";
    info.Sort(&record::name, std::less<std::string>());
    std::cout << info;

    std::cout << "\nSorted according to id:\n";
    info.Sort(&record::id, std::less<std::string>());
    std::cout << info;

    std::cout << "\nSorted according to pay:\n";
    info.Sort(&record::pay, std::greater<int>());
    // output example using iterators:
    for(auto& rec : info) {
        std::cout << rec << "\n";
    }

    std::cout << "\nSorted according to rate:\n";
    info.Sort(&record::rate, std::greater<int>());
    std::cout << info;

    std::cout << "\nSorted according to hours:\n";
    info.Sort(&record::hours, std::greater<int>());
    std::cout << info;

    // example using subscript, operator[]
    if(info.size()>2) {
        std::cout << "\ninfo[2] = " << info[2] << "\n";
    }
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
结构记录{
std::字符串名{};
std::字符串id{};
积分率=0;
整小时=0;
int pay=0;
//用于读取/写入记录的流运算符
friend std::istream&operator>>(std::istream&record&);

friend std::ofstream&Operator请在代码中添加一个或多个问题,同时仍能重现问题,例如,大量空行会使阅读变得困难您正在读取越界
array[i].pay>array[i+1].pay
其中条件为
i
,将
a
作为数组大小。运行valgrind或address sanitizer。快速查看,您的ID有5个字符长,但ID的字符串缓冲区只有5个字节长。您将没有足够的空间容纳空终止符,这意味着几乎所有与字符串相关的函数都将被删除具有极不可预测且通常危险的特性。请仔细阅读C字符串的工作方式和存储方式。这可能不是程序中唯一的问题。
    struct records info[n];
    double averageWages;
    int overTime = 0, i;
    infile.open("Project 3.dat");

    cout << "\n This week's employee history \n" << endl;

    if (infile.is_open()) {
        cout << " Name           Id            Rate          Hours  " << endl;
        take(info, n);

        cout << endl << endl;
        cout << "This week's payment\n" << endl;
        cout << " Name               Payment" << endl;
        calculator(info, n);
        swap(info, n);

        for (i = 0; i < n; i++) {
            cout << "*" << setw(10) << info[i].name << setw(10) << "$" << info[i].pay << endl;
        }
        averageWages = Average(info, n);

        cout << "\n\n" << "* The average wages of the employees: $" << averageWages << endl << endl;
    }

    else {
        cerr << "Error! file cannot open." << endl;
        exit(1);
    }
    return 0;
}
void take(records array[], const int a) {
    for (int i = 0; i < a; i++) {

        while (infile >> array[i].name >> array[i].id >> array[i].rate >> array[i].hours) {
            cout << "*" << setw(9) << array[i].name << setw(10) << array[i].id << setw(10) << "$" << array[i].rate << "/h" << setw(10) << array[i].hours << "h      " << endl;
        }
    } infile.close();
}
void swap(records array[], const int a) {
    bool tf; //true or false

    do {
        tf = false;

        for (int i = 0; i < a; i++) {

            if (array[i].pay > array[i + 1].pay) {
                swap(array[i], array[i + 1]);
                tf = true;
            }
        }
    } while (tf);

    records temp;

    for (int i = 0; i < a - 1; ++i)
    {
        for (int j = i + 1; j < a; ++j)
        {
            if (array[i].pay > array[j].pay)
            {
                temp = array[i];
                array[i] = array[j];
                array[j] = temp;
            }
        }
    }
}

To calculate average:

double Average(records array[], const int a) {

    double total = 0;
    double average;

    for (int i = 0; i < a; i++) {
        total = total + (array[i].pay);
        average = total / a;
    }

    cout.setf(ios::fixed);
    cout.setf(ios::showpoint);
    cout.precision(2);
    return (total / a);
}
int calculator(records array[], const int a) {



    infile.open("Project 3.dat");

    if (infile.is_open()) {

        for (int i = 0; i < a; i++) {
            infile >> array[i].name >> array[i].id >> array[i].rate >> array[i].hours;

            if (array[i].hours > 40) {
                int   overTime = (array[i].hours - 40)*1.5;
                array[i].pay = ((array[i].rate) * 40) + (overTime*(array[i].rate));
            }
            else {
                array[i].pay = (array[i].rate)*(array[i].hours);
            }
        }

        for (int i = 0; i < a; i++) {
            return (array[i].pay);
        }
    }
}
#include <iostream>
#include <vector>
#include <iomanip>
#include <sstream>
#include <fstream>
#include <numeric>
#include <algorithm>
#include <functional>

struct record {
    std::string name{};
    std::string id{};
    int rate = 0;
    int hours = 0;
    int pay = 0;

    // stream operators for reading/writing a record
    friend std::istream& operator>>(std::istream&, record&);
    friend std::ofstream& operator<<(std::ofstream&, const record&);
    friend std::ostream& operator<<(std::ostream&, const record&);
};

// populate a record from an istream
std::istream& operator>>(std::istream& is, record& r) {
    std::string line;
    // get a line and check that it's > 30 chars long
    if(std::getline(is, line) && line.size()>30) {
        // extract the name and remove trailing spaces
        r.name = line.substr(0, 30);
        auto pos = r.name.find_last_not_of(' ');
        if(pos != std::string::npos)
            r.name = r.name.substr(0, pos+1);

        // put the rest of the line in a stringstream
        std::stringstream ss(line.substr(30));
        // and extract the rest of the fields
        if(ss >> r.id >> r.rate >> r.hours) {
            // calculate pay
            r.pay = r.rate * r.hours;
        } else { // if extraction fails, set the stream in fail mode
            is.setstate(std::ios_base::failbit);
        }
    } else is.setstate(std::ios_base::failbit);

    return is;
}

// streaming a record to an ofstream (like a file)
std::ofstream& operator<<(std::ofstream& os, const record& r) {
    os << std::setw(30) << std::left << r.name.substr(0, 30) << r.id << " " << r.rate << " " << r.hours << "\n";
    return os;
}

// streaming a record to a generic ostream (like std::cout)
std::ostream& operator<<(std::ostream& os, const record& r) {
    os << "* " << std::setw(30) << std::left << r.name << std::right << r.id
       << " $" << r.rate << "/h " << r.hours << "h $" << std::setw(4) << r.pay;
    return os;
}

class Records { // a class to maintain a number of "record"s
    std::vector<record> m_records{}; // stores all "record"s
public:
    Records(const std::string& filename) {
        record tmp;
        std::ifstream e(filename); // open file
        // and extract one record at a time and put it in m_records.
        while(e>>tmp) m_records.emplace_back(std::move(tmp));
    }

    // sum on any member in "record"
    template <typename field>
    auto Sum(field f) const {
        return std::accumulate(m_records.begin(), m_records.end(), 0,
                    [&](int a, const record& b) { return a + (b.*f); });
    }

    // average of any member in "record"
    template <typename field>
    auto Average(field f) const {
        return static_cast<double>(Sum(f)) / m_records.size();
    }

    // sorting on any member in "record"
    template <typename field, typename T>
    void Sort(field f, const T& cmp) {
        std::sort(m_records.begin(), m_records.end(),
                [&](const record& a, const record& b){ return cmp(a.*f, b.*f); });
    }

    // return the number of "record" elements
    std::vector<record>::size_type size() const { return m_records.size(); }

    // access an element via subscript
    record& operator[](std::vector<record>::size_type idx) { return m_records[idx]; }
    const record& operator[](std::vector<record>::size_type idx) const { return m_records[idx]; }

    // iterators to use in for-loops
    std::vector<record>::const_iterator cbegin() const noexcept { return m_records.cbegin(); }
    std::vector<record>::const_iterator cend() const noexcept { return m_records.cend(); }
    std::vector<record>::const_iterator begin() const noexcept { return cbegin(); }
    std::vector<record>::const_iterator end() const noexcept { return cend(); }
    std::vector<record>::iterator begin() noexcept { return m_records.begin(); }
    std::vector<record>::iterator end() noexcept { return m_records.end(); }

    // stream operator to show all records
    friend std::ostream& operator<<(std::ostream&, const Records&);
};

std::ostream& operator<<(std::ostream& os, const Records& R) {
    os << "  Name                            Id  Rate  Hrs  Pay\n";
    for(const auto& r : R) std::cout << r << "\n";

    os << std::setprecision(2) << std::fixed;
    os << "Average pay         : $" << std::setw(7) << R.Average(&record::pay) << "\n";
    os << "        rate        : $" << std::setw(7) << R.Average(&record::rate) << "\n";
    os << "        hours worked:  " << std::setw(7) << R.Average(&record::hours) << "h\n";
    return os;
}

int main() {
    // create a "Records" entity called "info" by reading a file
    Records info("Project 3.dat");

    // misc sorting and showing the result
    std::cout << "Sorted as read from the file:\n";
    std::cout << info;

    std::cout << "\nSorted according to name:\n";
    info.Sort(&record::name, std::less<std::string>());
    std::cout << info;

    std::cout << "\nSorted according to id:\n";
    info.Sort(&record::id, std::less<std::string>());
    std::cout << info;

    std::cout << "\nSorted according to pay:\n";
    info.Sort(&record::pay, std::greater<int>());
    // output example using iterators:
    for(auto& rec : info) {
        std::cout << rec << "\n";
    }

    std::cout << "\nSorted according to rate:\n";
    info.Sort(&record::rate, std::greater<int>());
    std::cout << info;

    std::cout << "\nSorted according to hours:\n";
    info.Sort(&record::hours, std::greater<int>());
    std::cout << info;

    // example using subscript, operator[]
    if(info.size()>2) {
        std::cout << "\ninfo[2] = " << info[2] << "\n";
    }
}