使用cin跳过scanf()等预期字符

时间:2014-02-13 20:30:04

标签: c++ iostream scanf cin cstdio

如何在C ++中使用scanf("%d # %d",&a,&b);实现cin种效果?

5 个答案:

答案 0 :(得分:3)

您可以通过将#提取为一个字符来跳过std::istringstream iss("10 # 20"); int main() { int a, b; char hash; iss >> a >> hash >> b; assert(a == 10 && b == 20); }

{{1}}

答案 1 :(得分:3)

您可以创建自己的流操纵器。这很容易。

#include <ios>
#include <iostream>
using namespace std;

// skips the number of characters equal to the length of given text
// does not check whether the skipped characters are the same as it
struct skip
{
    const char * text;
    skip(const char * text) : text(text) {}
};

std::istream & operator >> (std::istream & stream, const skip & x)
{
    ios_base::fmtflags f = stream.flags();
    stream >> noskipws;

    char c;
    const char * text = x.text;
    while (stream && *text++)
        stream >> c;

    stream.flags(f);
    return stream;
}

int main()
{
    int a, b;
    cin >> a >> skip(" # ") >> b;
    cout << a << ", " << b << endl;
    return 0;
}

答案 2 :(得分:1)

遗憾的是,istream类中没有一个模仿它的直接函数。您可以使用一些函数来操作流并获得正确的输入,但我不熟悉它们的工作方式,所以我无法告诉您如何操作。

关于我个人如何做的最好的建议是使用getline()将输入放入字符串然后从那里我会做一些检查以查看它是否与格式匹配。所以在你的情况下,我会抓住第一个子字符串,直到第一个空格,确保它是一个有效的小数,检查以确保井号('#')在正确的位置,然后获取结束数字以确保它是有效。如果这三个对象中的任何一个不正确,我会将一些布尔变量设置为false以踢出或返回或指示输入无效且格式不正确的东西。

伪代码:

...

getline(cin,myStr);

while(!formatCheck(myStr))
{
    cout<<"Not valid format for input";
    getline(cin,myStr);
}

...

bool formatCheck(string str)
{
    string firstPart=str.subString(0,firstSpaceLocation);
    string middle=str[firstSpaceLocation+1];
    string lastPart=str.subString(firstSpaceLocation+3,end);

    if(first part not a valid number || middle!="#" || last part not a valid number)
    {
        return false;
    }

    return true;
}

答案 3 :(得分:1)

这是另一种方式。您可以通过区域设置中的#方面将std::ctype<char>分类为空白字符:

#include <iostream>
#include <sstream>
#include <vector>

namespace detail
{
    enum options { add, remove };

    class ctype : public std::ctype<char>
    {
    private:
        static mask* get_table(const std::string& ws, options opt)
        {
            static std::vector<mask> table(classic_table(),
                                           classic_table() + table_size);
            for (char c : ws)
            {
                if (opt == add)
                    table[c] |= space;
                else if (opt == remove)
                    table[c] &= ~space;
            }
            return &table[0];
        }
    public:
        ctype(const std::string& ws, options opt)
            : std::ctype<char>(get_table(ws, opt)) { }
    };
}

class adjustws_impl
{
public:
    adjustws_impl(const std::string& ws, detail::options opt) :
        m_ws(ws),
        m_opt(opt)
    { }

    friend std::istream& operator>>(std::istream& is,
                                    const adjustws_impl& manip)
    {
        is.imbue(std::locale(is.getloc(),
                             new detail::ctype(manip.m_ws, manip.m_opt)));
        return is;
    }
private:
    std::string m_ws;
    detail::options m_opt;
};

adjustws_impl setws(const std::string& ws)
{
    return adjustws_impl(ws, detail::add);
}

adjustws_impl unsetws(const std::string& ws)
{
    return adjustws_impl(ws, detail::remove);
}

int main()
{
    std::istringstream iss("10 # 20");
    int a, b;

    iss >> setws("#");
    iss >> a >> b;

    iss >> unsetws("#");
    std::cout << a << ' ' << b; // 10 20
} 

答案 4 :(得分:0)

您可以使用std :: istream :: ignore

跳过#或任何单个字符
std::istringstream sstr("1024 # 768");

int main()
{
   int a, b;
   sstr >> a; 
   sstr.ignore(256,'#');   // ignore until hash character
   sstr >> b;
   std::cout << "a: " << a << " b: " << b << std::endl;
}