使用CSV C ++修复发票号

时间:2017-04-18 13:37:14

标签: c++

我有一位客户从供应商处获得csv发票,大部分CSV都是错误的,所以我制作了一个小程序来修复它。这一切都很有效,除了一部分,发票号码,这绝对是一个逻辑问题,我正在努力想办法。

我已将csv中的每一列推到了矢量<字符串>为了便于管理,这样:

    ifstream input(path);
if (input.is_open()) {
    for (string line; getline(input, line); )
    {
        auto arr = explode(line, ',');
        // Now create seperate arrays for each field. Field won't change as CSV is by number of commas.
        contact.push_back(arr[0]);
        InvoiceNumber.push_back(arr[10]);
        InvoiceDate.push_back(arr[12]);
        DueDate.push_back(arr[13]);
        Description.push_back(arr[15]);
        Quantity.push_back(arr[16]);
        UnitAmount.push_back(arr[17]);
        AccountCode.push_back(arr[19]);
        TaxType.push_back(arr[20]);

    }
}

爆炸功能的命名只是因为我使用了很多PHP而且对我来说感觉更直观。它的代码如下:

vector<string> explode(string const & s, char delim){
vector<string> result;
istringstream iss(s);
for (string token; getline(iss, token, delim); ){
    result.push_back(move(token));
}
return result;

}

然后我接受它并通过Contact循环它,因为它们都应该包含相同数量的元素(并且它们似乎在实践中)。有时,同一个客户将拥有2条具有相同发票号的行,通过保持它们相同,它只会在其发票上添加新行。我需要为它们添加INV-前缀,并根据NumStart保存的用户输入更改数字。我试着这样做:

for (int i = 1; i < contact.size(); i++) {
    if (InvoiceNumber[i] == splotch) { InvoiceNumber[i] = InvoiceNumber[i - 1]; }
    else {
        char temp[10];
        splotch = InvoiceNumber[i];
        InvoiceNumber[i] = itoa(NumStart + i, temp, 10);
        InvoiceNumber[i] = "INV-" + InvoiceNumber[i];       
    }

我创建了splotch,其中包含最后一个发票号,以便我可以将当​​前号码与之前的发票号码进行比较而不使用inv前缀(因为未修改的号码没有此前缀)。

但是由于我这样做,数组只设置了一半的新数字,所以发票号码跳过这样:

https://gyazo.com/89007923ffad5df4c8bd7ce8b5a205e3

在矢量字符串和int之间进行转换以尝试制作1次存储似乎以某种方式写入损坏的数据。

如何正确地增加1001,1002,1003和1004的增量,而不是我正在进行的1 3 5 9废话?

2 个答案:

答案 0 :(得分:0)

您真的只需要将vecInput替换为您的发票矢量。当副本发票没有直接在第一个发票之后,这也能够正确打印。我不知道这是否是理想的,甚至不是问题。

// heidi.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <vector>
#include <string>
#include <iostream>
#include <unordered_map>


int main()
{
    const std::string sPrepend = "INV-";

    std::unordered_map<std::string, uint_fast32_t> mapRelations;

    std::vector<std::string> vecInput = {
        "330052", "330052", "330053", "330053", "330054", "330054"
    };

    std::string sStart;
    std::cout << "Please enter the start invoice: ";
    std::cin >> sStart;

    auto nStart = std::stoi(sStart);
    uint_fast32_t nCounter = 0;

    for (auto& invoice : vecInput)
    {
        if (mapRelations.find(invoice) == mapRelations.end())
        {
            mapRelations[invoice] = nCounter;
            std::cout << sPrepend + std::to_string(nStart + nCounter) << std::endl;
            nCounter++;
        }
        else
        {
            std::cout << sPrepend + std::to_string(nStart + mapRelations[invoice]) << std::endl;
        }
    }

    std::cin.get();

    return 0;
}

输出:

output

答案 1 :(得分:0)

据我所知,我已经编程了这个,代码评论很好,你可以理解。但是由于你的解释不好,我得不到你需要的东西。我作为评论要求的声誉较低!

class Adder
{
private:
    // I think this is your vector we will be adding up all our invoice numbers
    std::vector<std::string> invoice_number;
    // This holds the current invoice no
    int currentInvoiceNumber;
public:
    Adder() { currentInvoiceNumber = 0; } // Initialize with a constructor IDK what is splotch
    void add_number(int no)
    {
        if (no == currentInvoiceNumber) invoice_number.push_back("INV-" + std::to_string(no += 1)); 
        else
        {
            currentInvoiceNumber = no;
            add_number(currentInvoiceNumber); // recursion could reduce some code
        }
    }
    // let us see what we got
    void show_output()
    {
        // we could use iterators to access those contents
        typedef std::vector<std::string>::iterator iterator;
        iterator itr1 = invoice_number.begin();
        iterator itr2 = invoice_number.end();
        for (iterator itr = itr1; itr!=itr2; ++itr)
        {
            std::cout << *itr<<"\n";
        }
    }
};

我们会看到我们的示例输入

int main()
{
    Adder add;
    // for simplicity I used your input as arrays
    int arr[6] = { 1000,1000,1001,1001,1002,1002 };
    for (int i = 0; i < 6; i++)add.add_number(arr[i]);
    add.show_output();
}

结果是你想要的结果!

enter image description here

注意 我完全不了解你的问题,据我所知,我已经实施了。如果您有任何问题,请简要解释一下。 2.抱歉错误的骆驼套管就像这样,个人对我来说更容易!

最新修改 如果您需要将发票号作为std :: string传递,但发票号码是一个整数,那么您可以像这样进行一些小的类型转换

// Un-tested code without any exception handling
    void add_number(std::string number)
    {
        int no = std::stoi(number);
        if (no == currentInvoiceNumber) invoice_number.push_back("INV-" + std::to_string(no += 1)); 
        else
        {
            currentInvoiceNumber = no;
            add_number(std::to_string(currentInvoiceNumber)); // recursion could reduce some code
        }
    }

添加发票号的方法。请确保使用try和catch正确处理此方法。然而,你的发票号码是1000,1001,1002 .. n这似乎是一个整数,我想你可能不会遇到问题。

您现在可以修改main方法以将字符串作为输入

Adder add;
    // for simplicity I used your input as arrays
    std::string arr[6] = { "1000","1000","1001","1001","1002","1002" };
    for (int i = 0; i < 6; i++)add.add_number(arr[i]);
    add.show_output();