【问题标题】:How to get specific part of line in specific format in directories? [closed]如何在目录中以特定格式获取行的特定部分? [关闭]
【发布时间】:2014-01-08 19:26:43
【问题描述】:
------------------------------------------------
          Artikli vo magacin za obleka          
------------------------------------------------
Vo magacinot ima vkupno 5 artikli
------------------------------------------------
Sifra : 3
Opis : opis2
Edinecna cena : 212
Vlezna kolicina : 2
Izlezna kolicina : 0
Danocna stapka : 0
Iznos : 424
Datum na vlez : 20324
------------------------------------------------
Sifra : 3
Opis : 54
Edinecna cena : 123
Vlezna kolicina : 12
Izlezna kolicina : 0
Danocna stapka : 0
Iznos : 1476
Datum na vlez : 120915
------------------------------------------------
Sifra : 3
Opis : opsi2
Edinecna cena : 12
Vlezna kolicina : 324
Izlezna kolicina : 0
Danocna stapka : 0
Iznos : 3888
Datum na vlez : 570509
------------------------------------------------
Sifra : 2
Opis : vopi
Edinecna cena : 2
Vlezna kolicina : 2
Izlezna kolicina : 0
Danocna stapka : 0
Iznos : 4
Datum na vlez : 951230
------------------------------------------------
Sifra : 1
Opis : opis1
Edinecna cena : 2
Vlezna kolicina : 2
Izlezna kolicina : 0
Danocna stapka : 0
Iznos : 4
Datum na vlez : 101
------------------------------------------------

上面是一个名为“directory.dat”的文件,我想知道如何取出包含特定文本的特定行的整数?例如,如果我想对所有带有“Edinecna cena”的行求和,我该如何专门从这些行中获取所有整数?

【问题讨论】:

  • 您需要拉入所有行,解析行并搜索第一个非字符。以这种方式查找整数,看起来所有“:”也在所有整数之前,因此您可以将其用作分隔符。
  • awk '/Edinecna cena/ {sum+=$NF;print $NF} END {print sum}'?
  • @twalberg 这是什么意思?
  • @Matt2234 你能告诉我我应该用什么来解析吗?还有,整数前面的小空格会不会造成问题?
  • 意思是“打印匹配“Edinecna cena”的每一行的最后一个字段,并在末尾打印所有这些字段的总和......

标签: c++ fstream ifstream directory ofstream


【解决方案1】:

您可以逐行读取您的文件(0x499602D2 建议不使用eof() 的正确方法):

ifstream dir("directory.dat");
string line;
while(getline(dir, line)){
    //(process the line)
}

检查您的行 (string priceLn = "Edinecna cena : ";) 是否与行首匹配,并提取价格:

// process the line:
if(line.find(priceLn)==0){
    price = stoi(line.substr(priceLn.size()));
}

PS: strncmp() 在读取文件时会产生较小的开销。我们可以像这样重写 if 语句:

if(line.size() >= priceLn.size() && 
   strncmp(line.c_str(), priceLn.c_str(), priceLn.size()) == 0) {...}

【讨论】:

  • 我究竟如何只“提取”价格?
  • @user2699298 它在price = stoi(line.substr(priceLn.size())); 行中被提取或者您可以使用+= 运算符累积所有价格。
  • while (!eof()) 根本上是错误的。将其更改为while (getline(dir, line))
  • @0x499602D2 std::getline() 返回istream&eof() 怎么了?
  • getline 确实返回istream,但operator bool()operator void* pre-C++11)检查!fail()。仅当流无法提取时,循环才应退出。
【解决方案2】:

您可以使用正则表达式库并创建一个正则表达式来为您逐行解析文件。

/(Edinecna cena) : (\d+)/ 将作为您要求的示例的解决方案。该整数将包含在第二组中,您可以将第一组中的项目替换为您要搜索的任何内容。

【讨论】:

  • 我以前从未在 C++ 中使用过正则表达式,但正如我所见,库 #include <regex> 似乎只在 C++11 中可用,我不能在这个项目中使用它。
  • 如果是这样,那么一个简单的 strncmp 就足够了。在每一行调用它,n 是您要查找的字符串的长度,然后在该行中找到 ':',为其索引 +2,并将从那里开始的字符串转换为整数。这也可以,只是不如正则表达式干净。
  • 您介意在我的示例中提供一些关于如何使用 strncmp 的 sn-p 吗?只需 strncmp 中的参数就足够了。
  • if(strncmp("Edinecna cena", inLine, strlen("Edinecna cena")) == 0) { /* String matches */ }
  • 这里的 inLine 到底是什么?我们要比较的那一行的内容是什么?
猜你喜欢
  • 2016-08-03
  • 2019-07-07
  • 2013-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多