c++ - sscanf 拒绝整数读取中的前导零

标签 c++ c scanf

我想使用 sscanf 创建一个简单的“日期”读取,它接受以下输入:

"dd/mm/yyyy"

“dd”和“mm”字段都可以是 2 位长(例如 0、6 或 11,但不能是 123)。 “年”字段可以是 0 或四位数字字段。这三个字段中的任何一个值为 0 都意味着必须取而代之的是系统的日、月或年。

该格式必须严格,因此,如果输入的格式不符合模式,则必须通知用户。

我的尝试是:

int d, m, y;
char const* input = "23/7/1990";

int n = sscanf(input, "%2u/%2u/%4u", &d, &m, &y);

if (n != 3) throw InvalidDate("Invalid format");

// Fill 0 values with system date.
// Check date correctness with `mktime` and `localtime`.

问题是这种 sscanf 格式接受不允许的输入:

char const* invalid1 = "23/ 12/ 1990";
char const* invalid2 = "23/12/1990/123whatever......."

那么,是否有任何技巧/修饰符可以拒绝整数前的前导零、标记字符串的结尾,或者在解析更多输入时导致可检测到的错误?

对于最后一种情况(invalid2;字符串末尾可检测到的故障),可能的解决方案是:

int d, m, y;
char trick;

char const* input = "23/7/1990";

int n = sscanf(input, "%2u/%2u/%4u%c", &d, &m, &y, &trick);

// If it fills four fields, means the input was too long.
if (fields != 3) throw InvalidDate("Invalid format");

// Fill 0 values with system date.

但我不知道是否有更好的方法来检测字符串结尾。更重要的是,这种“格式”(以 '%c' 开头)导致 sscanf 认为输入的有效日期是错误的(例如,“23/6/1990”导致最后一个字符不是填充;如果使用 scanf 而不是 sscanf,则会设置 ferror)。我什至尝试过使用 "%2u/%2u/%4u\0" 但编译器警告我“格式嵌入\0”。

那么,不使用正则表达式或 stringstream 的最佳解决方案是什么?

对了,有没有其他方法可以“欺骗”sscanf

最佳答案

您可以使用 boost regex 库,它可以做很多这些事情。检查下面的代码:

#include <boost/regex.hpp>
#include <iostream>
#include <string>

int main()
{
    // Expression to match
    boost::regex e("(^\\d{1,2})/(\\d{1,2})/(\\d{4})$");

    // Results are here
    boost::match_results<std::string::const_iterator>  results;

    std::string val_to_match = "1/11/1990";
    if (boost::regex_search(val_to_match, results, e) && results.size() == 4) {
        std::cout << "Matched "  << results[0] << std::endl; 
        int i = 1;
        while (i < 4) {
            std::cout << "Value: " << i <<  "  "<< results[i] << std::endl;
            i++;
        }
    } else {
        std::cout << "Couldn't match \n";
    }

    return 0;
}

关于c++ - sscanf 拒绝整数读取中的前导零,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30275680/

相关文章:

python - 如何使用 boost.python 将预填充的 "unsigned char*"缓冲区传递给 C++ 方法?

c - 警告 : Function must be extern error in C

c - 将包含指针的结构写入磁盘

c - 使用 scanf() 时的段错误

c++ - 有人也在使用结构名称作为变量名称。代码真正说的是什么?

c++ - 如何增加 7z.exe 的可移植性

c++ - 避免舍入错误(特别是 float )c++

C# 漂亮的代码打印库

c - 为什么在使用 Win32 ConsoleInput 函数时 scanf 不起作用?

c - 从c中的文本文件读取 float 时出现错误值