我正在解析包含这样的模式的文件
[0] [NAME] [描述]
我正在使用
fscanf(fp, "[%d][%s][%s]", &no, &name, &desc)
并获取这些值no = 0和name = NAME] [DESCRIPTION]和desc = junk。我尝试在[0]和[Name]之间添加空格,导致no = 0和name = NAME]我在这里做错了什么?
答案 0 :(得分:7)
将%s
替换为%[^]\n]
。 %s
消耗了]
,您需要将name
限制为允许的字符。
此处]
和\n
不允许放入name
。您可能希望%[A-Za-z_ ]
将name
限制为字母,_和空格。
相关改进:
长度说明符,以避免超出
考虑fgets()
与sscanf()
vs fscanf()
配对。
答案 1 :(得分: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!
}