2

我正在解析一个包含这样的模式的文件

[0][姓名][描述]

我在用 fscanf(fp, "[%d][%s][%s]", &no, &name, &desc)

并获取这些值 no=0 和 name=NAME][DESCRIPTION] 和 desc = junk。我尝试在 [0] 和 [Name] 之间添加空格,这导致 no = 0 和 name=NAME] 我在这里做错了什么?

4

2 回答 2

7

将两者都替换%s%[^]\n]%s正在消耗]并且您需要将 限制为name允许的字符。

这里]\n不允许放入name。您可能希望%[A-Za-z_ ]限制name为字母、_ 和空格。


相关改进:
避免溢出的长度说明符。
考虑与vsfgets()配对。sscanf()fscanf()

于 2013-07-30T21:50:02.370 回答
0

%s读取直到找到空白字符,scanf在这里无法满足您的需求。你需要别的东西。幸运的是,C++ 让这一切变得简单。

我有这些函数,我在字符串或字符文字中使用哪个流,只需将它们粘贴在标题中:

#include <iostream>
#include <string>
#include <array>
#include <cstring>

template<class e, class t, int N>
std::basic_istream<e,t>& operator>>(std::basic_istream<e,t>& in, const e(&sliteral)[N]) {
        std::array<e, N-1> buffer; //get buffer
        in >> buffer[0]; //skips whitespace
        if (N>2)
                in.read(&buffer[1], N-2); //read the rest
        if (strncmp(&buffer[0], sliteral, N-1)) //if it failed
                in.setstate(std::ios::failbit); //set the state
        return in;
}
template<class e, class t>
std::basic_istream<e,t>& operator>>(std::basic_istream<e,t>& in, const e& cliteral) {
        e buffer;  //get buffer
        in >> buffer; //read data
        if (buffer != cliteral) //if it failed
                in.setstate(std::ios::failbit); //set the state
        return in;
}
//redirect mutable char arrays to their normal function
template<class e, class t, int N>
std::basic_istream<e,t>& operator>>(std::basic_istream<e,t>& in, e(&carray)[N]) {
        return std::operator>>(in, carray);
}

除了标准库之外,还有这些,扫描有点奇怪,但很简单:

int id;
std::string name;
std::string description;

std::cin >> "[" >> id >> "][";
std::getline(std::cin, name, ']'); //read until ]
std::cin >> "][";
std::getline(std::cin, description, ']');  //read until ]
std::cin >> "]";

if (std::cin) {
    //success!  All data was properly read in!
}
于 2013-07-30T21:50:44.903 回答