【问题标题】:When reading in a .txt file in c++, how do I change a number that's stored in the .txt file as "365048" to "36, 50, 48" using a dynamic array?在 C++ 中读取 .txt 文件时,如何使用动态数组将存储在 .txt 文件中的数字从“365048”更改为“36、50、48”?
【发布时间】:2020-07-29 19:40:49
【问题描述】:

我一直在尝试将存储在 .txt 文件中的数字分隔为“365048”到“36、50、48”,当它已使用动态数组读入我的程序时,我不确定我在哪里出错了。我遇到问题的变量是 int* purchase。

Main.cpp 中的代码

// Repeat_Assessment_C++_Aisling.cpp : This file contains the 'main' function. Program execution begins and ends there.
//

#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <vector>
#include "Customer.h"
using namespace std;

void OutputFileStream();
void parseLine(const string& str);
void InputFileStream();
//void printActions();


void OutputFileStream()
{
    cout << "Creating and writing to file: Customer.txt" << endl;

    ofstream outStream("customers.txt");  // write mode (overwrites existing data)

    if (outStream.good())
    {
        int customerID = 150033;
        outStream << "This is a line of text.\n";
        outStream << "This is another line of text.\n";
        outStream << "This is a line of text.\n";
        int numOfPurchases = 4;
        int purchases = 0;
        outStream << customerID << "Mr" << "Jack" << "New" << numOfPurchases << purchases << endl;

        outStream.close(); //  close file
        cout << "File written.\n" << endl;
    }
    else
        cout << "Unable to open file";
}

void parseLine(const string& str) {

    stringstream strStream(str); //create string stream from the string
   // int customerID;
    string title;
    string name;
    string type;
    //int numOfPurchases;
    //int purchases;
    string s;
   
    int customerID = 150033;
    getline(strStream, s, ';');
    customerID = stoi(s);

    getline(strStream, title, ';');
    getline(strStream, name, ';');
    getline(strStream, type, ';');

    int numOfPurchases = 4;
    getline(strStream, s, ';');
    numOfPurchases = stoi(s);

    int purchases = 0;
    getline(strStream, s, ';');
    purchases = stoi(s);
    int* purchasesArray = new int[3];
    purchasesArray[0] = (purchases & (255 << 24)) >> 24;
    purchasesArray[1] = (purchases & (255 << 16)) >> 16;
    purchasesArray[2] = (purchases & (255 << 8)) >> 8;
    for (int i = 0; i < 3; i++)
    {
        int purchasesArray[3];
    }

    cout << " CustomerID: " << customerID << "Title:" << title << " Name: " << name << " Type:" << type << " Number of Purchases: " << numOfPurchases << "Purchases: " << purchases << endl;
}

void InputFileStream() {
    cout << "Reading from a semi-colon delimited txt file" << endl;

    string line;
    ifstream inStream("customers.txt"); //opens file as an input file stream
    if (inStream.good()) //if the file is opened successfully and not empty
    {
        while (getline(inStream, line)) //reads line until false return
        {
            parseLine(line);
        }
        inStream.close();
    }
    else
        cout << "unable to open file or the file is empty!";
}

int main()
{
     InputFileStream();

    Customer cust1;

    cust1.setCustomerID(150032);
    cust1.setTitle("Mr");
    cust1.setName("Joey");
    cust1.setNumOfPurchases(3);
    cust1.setPurchases(366, 352, 334);
    cust1.setType("New");

    cout << cust1.getCustomerID() << endl;
    cout << cust1.getTitle() << endl;
    cout << cust1.getName() << endl;
    cout << cust1.getNumOfPurchases() << endl;
    cout << cust1.getPurchases() << endl;
    cout <<  cust1.getType() << endl;
   
   


    return 0;
   

}

来自 Customer.h 的代码

#pragma once
#include<iostream>
using namespace std;
#include<string>

class Customer
{
private:
    int customerID;
    string title;
    string name;
    int numOfPurchases;
    int* purchases;
    string type;

public:
    Customer(); // default constructor
    Customer(int customerID, string title, string name, int numOfPurchases, int purchase1, int purchase2, int purchase3, string type);
    
    //copy overload assignment
    Customer& operator=(Customer& otherCustomer);
    Customer(const Customer& source);

    ~Customer(); //destructor

    //Getters and Setters
    void setCustomerID(int customerID);
    void setTitle(string title);
    void setName(string name);
    void setNumOfPurchases(int numOfPurchases);
    void setPurchases(int purchase1, int purchase2, int purchase3);
    void setType(string type);

    int getCustomerID();
    string getTitle();
    string getName();
    int getNumOfPurchases();
    int* getPurchases();
    string getType();

    void printCustomer() {
        cout << customerID << "," << title << "," << name << "," << numOfPurchases << "," << purchases << "," << type << endl;
    }

    friend std::ostream& operator<<(std::ostream& out, Customer& customer); // overloaded operator<<
    friend istream& operator>> (istream& in, Customer& customer); // overloaded operator >>
};

来自 Customer.cpp 的代码

#include "Customer.h"
#include <iostream>
#include <string>
#include<utility>
using namespace std;

//default constructor
Customer::Customer() {
}


//Full constructor
Customer::Customer(int customerID, string title, string name, int numOfPurchases, int purchase1, int purchase2, int purchase3, string type)
{
    this->customerID = customerID;
    this->title = title;
    this->name = name;
    this->numOfPurchases = numOfPurchases;
    purchases = new int[3];
    purchases[0] = purchase1;
    purchases[1] = purchase2;
    purchases[2] = purchase3;
    this->type = type;
}

Customer::Customer(const Customer& source) //copy constructor
{
    cout << "copy constructor called" << endl;
    this->customerID = source.customerID;
    this->title = source.title;
    this->name = source.name;
    this->numOfPurchases = source.numOfPurchases;
    this->purchases = new int[3];
    purchases[0] = source.purchases[0];
    purchases[1] = source.purchases[1];
    purchases[2] = source.purchases[2];
    this->type = source.type;
}

//overloaded assignment operator=
Customer& Customer::operator= (Customer& otherCustomer)
{
    cout << "Overloaded assignment operator= called" << endl;

    //self-assignment guard
    if (this == &otherCustomer)
        return *this;  //refernce to the same object

   // copy data from the source (rhs) to this object (the destination)
    name = otherCustomer.name;

    //must make a new scores object to store a copy of the other student 
    if (purchases != nullptr)
        delete[] purchases;

    purchases = new int[3];
    for (int i = 0; i < 3; i++) {
        purchases[i] = otherCustomer.purchases[i];
    }

    //return this existing object so we can chain this operator 
    return *this;
}
Customer::~Customer() {
    cout << "Destructor ~Customer called" << endl;
    delete[] purchases;
}

// Overloaded insertion operator  (Outputs Character object data as an output stream)
// Defined in header file as a  "friend" function, as it is not a member function
//
ostream& operator<<(ostream& out, Customer& customer)
{
    cout << "Customer details ( output by insertion operator<< )" << endl;
    cout << "Customer ID: " << customer.customerID << endl;
    cout << "Title: " << customer.title << endl;
    cout << "Name: " << customer.name << endl;
    cout << "Number of purchases: " << customer.numOfPurchases << endl;
    cout << "Purchases: ";
    for (int i = 0; i < 3; i++)
    {
        if (i > 0) cout << ",";
        cout << customer.purchases[i];
    }
    cout << "Type: " << customer.type << endl;
    
    return out;
}


istream& operator>> (istream& in, Customer& customer)
{
    cout << "Enter Customer details ( using the extraction operator>> )" << endl;
    cout << "Enter Customer ID: " << endl;
    cin >> customer.customerID;
    cout << "Enter Title: " << endl;
    getline(cin, customer.title);
    cout << "Enter Name: " << endl;
    getline(cin, customer.name);
    cout << "Enter Number of Purchases: ";
    cin >> customer.numOfPurchases; 
    cout << "Enter Purchases: ";
    cin >> customer.purchases[0];
    cin >> customer.purchases[1];
    cin >> customer.purchases[2];
    cout << "Enter Type";
    getline(cin, customer.type);
    cout << endl;

    return in;
}

int Customer::getCustomerID()
{
    return customerID;
}

string Customer::getTitle()
{
    return title;
}

string Customer::getName()
{
    return name;
}

int Customer::getNumOfPurchases()
{
    return numOfPurchases;
}

int* Customer::getPurchases()
{
    return purchases;
}

string Customer::getType()
{
    return type;
}

void Customer::setCustomerID(int customerID)
{
    if (customerID < 1) {
        cout << "Customer ID has to be equal to 1 or more" << endl; //Changed all the "throw invalid_argument" messages to cout as they were causing an issue with my main.cpp file and an abort message kept appearing every time I ran my main.cpp file.
    }
    this->customerID = customerID;
}

void Customer::setTitle(string title)
{
    if (title.length() < 2) {
        cout << "Title has to be more than or equal to 2 characters" << endl;
    }
    this->title = title;
}

void Customer::setName(string name)
{
    if (name.length() < 4) {
        cout << "Length of name should be more than or equal to 4 characters" << endl;
    }
    this->name = name;
}

//Got help ith this on stack overflow as I was using "&&" instead of using "||" for the if statement
void Customer::setNumOfPurchases(int numOfPurchases)
{
    if(numOfPurchases <0 || numOfPurchases > 10000){
        cout << "Number of purchases should be between 0 to 10000" << endl;
    }
    this->numOfPurchases = numOfPurchases;
}

void Customer::setPurchases(int purchase1, int purchase2, int purchase3)
{
    if (purchase1 < 0 || purchase2 < 0 || purchase3 < 0) {
        cout << "Purchases must be more than or equal to zero" << endl;
    }
}

//Got help from stack overflow on comparing strings as I originally didnt use "type.compare"
void Customer::setType(string type) {
    if (type.compare("New") !=0 || type.compare("Either") !=0) {
        cout << "Type of purchase has to be New or Either" << endl;
    }
}  

customers.txt 文件中的文本:

150034;Mr;Sean Brennan;New;5;365048;\n
150035;Mrs;Aisling Smith;Regular;6;375149;\n
150036;Mr;John Smith;New;7;385250;\n
150037;Mrs;Sharon Hanratty;Regular;8;395351;

【问题讨论】:

  • 评论不适用于扩展讨论或调试会话;这个对话是moved to chat

标签: c++ class file-io header-files dynamic-arrays


【解决方案1】:

问题似乎在于您正在尝试将输入划分为其十六进制数字,并且看起来您正在寻找十进制数字。 也许您可以执行以下操作:

purchasesArray[0] = purchases / 10000;
purchasesArray[1] = (purchases / 100) % 100;
purchasesArray[2] = purchases % 100;

而不是

purchasesArray[0] = (purchases & (255 << 24)) >> 24;
purchasesArray[1] = (purchases & (255 << 16)) >> 16;
purchasesArray[2] = (purchases & (255 << 8)) >> 8;

注意:如果您的输入非常大,上述解决方案的性能可能会很差。

注意2:即使你真的想要十六进制数字,你的解析也是有问题的。

修改注释 2:

要解析 6 位十六进制数,您可以这样做:

purchasesArray[0] = (purchases & (255 << 16)) >> 16;
purchasesArray[1] = (purchases & (255 << 8)) >> 8;
purchasesArray[2] = purchases & 255;

您的代码似乎解析了 8 位十六进制数的前 6 位数字。 这就是为什么我称之为问题。

【讨论】:

    猜你喜欢
    • 2020-05-25
    • 2012-11-27
    • 1970-01-01
    • 2013-03-24
    • 2022-01-05
    • 1970-01-01
    • 1970-01-01
    • 2021-10-25
    • 2016-05-03
    相关资源
    最近更新 更多