0

我正在使用 TIVA TM4C 在 SIM900 手机调制解调器中的 SIM 卡上获取有关余额和到期的消息。

下面是我用来解析字符串的代码。我很担心,因为代码依赖于特定位置的空间。如果我只能解析数字似乎会更可靠,并且根据顺序很容易确定哪个是美元、美分、月份等。

我可以使用更好的方法来解析数字吗?货币不是那么重要。

这是代码:

char *message = NULL;           // Balance and expiry message
char expiry[] = "00/00/00";     // Expiry date
char balance[] = "999.99";      // Remaining balance
char currency[] = "USD";        // Balance currency
char *ptr;                      // Pointer for parsing balance message 
int ctr=0;                      // For stepping through tokens

// Get the balance/expiry message
message = getMessage();

// The message will always look like this:
// +CUSD: 0,"Your account balance is 49.10 USD and will expire on 04/03/16.",64

// Parse
ptr = strtok (message," ");
while (ptr != NULL){
    ptr = strtok (NULL," ");
    if (ctr == 4) { strcpy(balance,ptr); }
    else if (ctr == 5) { strcpy(currency,ptr); }
    else if (ctr == 10) { strncpy(expiry,ptr,8); }
    ctr++;
}
4

1 回答 1

0

或者,如果您可以使用 boost,请考虑 Boost Spirit:

Live On Coliru

#include <boost/spirit/home/x3.hpp>
#include <boost/fusion/adapted/std_tuple.hpp>
#include <boost/date_time/gregorian/greg_date.hpp>
#include <boost/date_time/gregorian/gregorian_io.hpp>
#include <boost/multiprecision/cpp_dec_float.hpp>

int main() {
    using boost::gregorian::date;
    using Money = boost::multiprecision::number<boost::multiprecision::cpp_dec_float<20>, boost::multiprecision::et_off>;

    boost::gregorian::date expiry; // Expiry date
    Money balance;                 // Remaining balance
    std::string currency;          // Balance currency

    // The message will always look like this:
    for (std::string message : {
            "+CUSD: 0,\"Your account balance is 49.10 USD and will expire on 04/03/16.\",64",
        })
    {
        using namespace boost::spirit::x3;

        real_parser<Money> money_;
        int_parser<int, 10, 2, 2> int2_;

        auto to_date = [](auto& ctx) {
            using boost::fusion::at_c;
            auto& t = _attr(ctx);
            _val(ctx) = date(2000+at_c<2>(t), at_c<0>(t), at_c<1>(t));
        };

        auto date_  = rule<struct date_, date> { "date" }
                    = (int2_ >> '/' >> int2_ >> '/' >> int2_) [ to_date ];

        auto tied = std::tie(balance, currency, expiry);

        bool ok = phrase_parse(message.begin(), message.end(),
                omit [ *(char_ - "balance is") ]
                >> lexeme["balance is"] >> money_ >> lexeme[+graph]
                >> lexeme["and will expire on"] >> date_ >> omit[*char_] >> eoi,
                space, tied);

        assert(ok);
        std::cout << "Balance: "  << balance  << "\n";
        std::cout << "Currency: " << currency << "\n";
        std::cout << "Expiry: "   << expiry   << "\n";
    }
}

印刷

Balance: 49.1
Currency: USD
Expiry: 2016-Apr-03
于 2015-11-21T00:53:17.253 回答