【问题标题】:C++ Display unique date and its related price found in txt fileC ++显示在txt文件中找到的唯一日期及其相关价格
【发布时间】:2015-04-24 02:06:14
【问题描述】:

目前我有一个将用户输入存储在文本文件中的系统,以及一个计算当月每日销售额并显示当日销售额和当月总计的函数。

例如,这里是四月的一些文本文件数据:

1|Bag|2|3|6|20Apr2015
2|File|2.3|5|11.5|20Apr2015
3|File|2.3|5|15.5|20Apr2015
4|Book|0.9|5|4.5|22Apr2015
5|Pencil|0.9|5|4.5|25Apr2015
6|Ruler|0.9|5|4.5|20Jul2015
7|Eraser|0.9|5|4.5|20Jul2015
8|Bag|0.9|5|4.5|28Apr2015
9|File|0.9|5|4.5|20Apr2015

这是我当前的输出:

20Apr2015 $11.5
20Apr2015 $15.5
22Apr2015 $4.5
25Apr2015 $4.5
28Apr2015 $4.5
20Apr2015 $4.5
     Grand Total $45

但我想要的结果应该是这样的:

20Apr2015 $31.5
22Apr2015 $4.5
25Apr2015 $4.5
28Apr2015 $4.5
     Grand Total $45

它应该结合每天的所有销售额。

下面是我计算每日销售额的代码。谁能指导我如何获得我想要的输出?

struct TransactionPile
{
  // to record item information.
  string itemid;
  string itemdesc;
  float unitprice;
  int quantity;
  float totalprice;
  string date;
  time_t now = time(0);
};

//Function to calculate daily sales
void computeDailySales()
{
  // current date/time based on current system
  time_t now = time(0);
  // convert now to string form
  char* ct = ctime(&now);
  // convert now to tm struct for UTC
  tm *ltm = localtime(&now);
  char* dt = asctime(ltm);

  string itemid;
  float totalprice;
  float totalsales = 0;
  string date;
  int year;
  int month;
  int day;
  int found;
  string syear;
  string smonth;
  string sday;
  string sdate;

  //Get the value of year
  year = (1900 + ltm->tm_year); 
  //Convert the year to string and store into syear
  syear = static_cast<ostringstream*>( &(ostringstream() << year) )->str();

  //Get the value of month
  month = (1 + ltm->tm_mon);
  //Convert the month to string and store into smonth
  smonth =static_cast<ostringstream*>( &(ostringstream() << month) )->str();

  //Get the value of day
  day = ltm->tm_mday;
  //Convert the day to string and store into sday
  sday = static_cast<ostringstream*>( &(ostringstream() << day) )->str();

  //Store the different month name in smonth if condition met
  if (smonth =="1")
  {
    smonth ="Jan";
  }
  if (smonth =="2")
  {
    smonth ="Feb";
  }
  if (smonth =="3")
  {
    smonth ="Mar";
  }
  if (smonth =="4")
  {
    smonth ="Apr";
  }
  if (smonth =="5")
  {
    smonth ="May";
  }
  if (smonth =="6")
  {
    smonth ="Jun";
  }
  if (smonth =="7")
  {
    smonth ="Jul";
  }
  if (smonth =="8")
  {
    smonth ="Aug";
  }
  if (smonth =="9")
  {
    smonth ="Sep";
  }
  if (smonth =="10")
  {
    smonth ="Oct";
  }
  if (smonth =="11")
  {
    smonth ="Nov";
  }
  if (smonth =="12")
  {
    smonth ="Dec";
  }
  //Concatenate the sday, smonth, syear and store inside sdate
  sdate = sday + smonth + syear;    

  cout<<endl;
  for(int i = 0; i < MAX- 1; i++)
  {
    if(transactionpile[i].itemid !="")
    {
      //Find all related record according to the value in smonth
      found = transactionpile[i].date.find(smonth);
      if(found<transactionpile[i].date.length())
      {
        std::sort(transactionpile.begin(),transactionpile.end(), 
          [](TransactionPile a, TransactionPile b)
               {return a.rawdate<b.rawdate;});

        if(i<MAX-2&&transactionpile[i].date==transactionpile[i+1].date)
        {
          transactionpile[i+1].totalprice+=transactionpile[i].totalprice;
          continue;
        }
        //Add the totalprice of each found records to totalsalesmonth[k]
        totalsales += transactionpile[i].totalprice;
      }
    }
  }

  //Print out the total sales made on the day itself by system date
  cout << "            " << "Total Sale" << endl;
  cout << "            " << totalsales <<endl;
}

【问题讨论】:

  • 欢迎来到 Stack Overflow。我已经稍微编辑了你的问题。在代码部分,我用空格替换了制表符并调整了缩进以使代码更易于阅读(以及复制和粘贴)。我对英语做了一些更正。 (我们知道您的母语不是英语,我们并不期望完美,但这些更正使文本更易于阅读和理解。)我重新排列了数据和输出部分以反映逻辑:数据 --> 输出。

标签: c++ c++11 visual-c++ c++14


【解决方案1】:

在输出transactionpile 之前,请按日期对列表进行排序。

如果您想获得良好的排序(以便输出列表按顺序排列),请在结构中保留 time_t 值。现在假设这个新值将存储在rawdate 字段中。对于排序,您可以使用:

#include <algorithm>
...
std::sort(transactionpile.begin(),transactionpile.end(), 
    [](TransactionPile a, TransactionPile b){return a.rawdate<b.rawdate;}
    /*lambda function: required because std::sort doesn't know how to sort a TransactionPile
);

在您只需要通过添加以下代码来更改输出代码的代码之后:

if(i<MAX-2&&transactionpile[i].date==transactionpile[i+1].date){
    transactionpile[i+1].totalprice+=transactionpile[i].totalprice;
    continue; //goes to the next iteration (merge with the current one before printing)
}

这样,由于您的列表已排序,您将消除重复并最终获得良好的价值。这可能不是最干净的解决方案,但它可以完成工作并且不会在代码中添加太多行。

【讨论】:

  • 您好,感谢您花时间回答我的问题,需要与您确认一下,因为我存储在事务堆中的日期是字符串类型,我无法使用算术比较字符串类型> 或
  • 取决于您想要做什么:如果您不关心顺序,则字符串比较将用于查找重复项。至于良好的排序,在将日期放入字符串之前,您确实有更好的形式(如time_t)。你不能把它也存储在你的结构中吗?
  • 对于排序,您可以使用库函数。我建议您使用std::sort (en.cppreference.com/w/cpp/algorithm/sort),因为您可以定义自己的与 lambda 函数的比较。在这种情况下,函数将是 [](TransactionPile a, TransactionPile b){return a.date&lt;b.date;} 例如。我假设您可以轻松地在 transactionpile 上获得迭代器;由于您没有显示类型,我认为它是std::vector&lt;TransactionPile&gt;
  • 嗨,Meneldal,是的,我可以将 time_t 存储在我的结构中,所以在这种情况下,在我的结构中,我需要有年、月和日而不是日期,对吗?我对 C++ 很陌生,因此我问的问题有点奇怪。
  • 我看到了您为 std::sort 提供的示例,在示例中,有一个包含要排序的值的数组,在这种情况下,对于我来说,我必须存储该数组中的日期值?
猜你喜欢
  • 2018-04-21
  • 1970-01-01
  • 2015-01-12
  • 1970-01-01
  • 2023-03-23
  • 1970-01-01
  • 1970-01-01
  • 2019-04-20
  • 1970-01-01
相关资源
最近更新 更多