正如您可以使用的其他好的答案所指出的那样
-
find_first_of()、find_first_not_of() 和 substr() 来自 std::string 循环中
regex
但这可能太多了。我将添加 3 个您可能会发现的示例
更简单。
为了方便(我的)这里,前 2 个程序需要命令行上的文件名,测试文件是 in.txt。内容跟贴出来的一样
JACK1940383DAVID30284HAROLD68372TROY4392
最后一个例子只是解析声明为char[]的字符串数据
1。使用fscanf()
由于目标是使用格式化数据,fscanf() 是一个选项。由于数据结构很简单,所以程序就是一行循环:
char mask[] = "%50[^0-9]%50[0-9]";
while ( 2 == fscanf(F, mask, tk_key, tk_value))
std::cout << tk_key << "/" << tk_value << "\n";
程序输出
所有示例的输出都相同
JACK/1940383
DAVID/30284
HAROLD/68372
TROY/4392
ex 的代码。 1
#include <errno.h>
#include <iostream>
int main(int argc,char** argv)
{
if (argc < 2)
{ std::cerr << "Use: pgm FileName\n";
return -1;
}
FILE* F = fopen(argv[1], "r");
if (F == NULL)
{
perror("Could not open file");
return -1;
}
std::cerr << "File: \"" << argv[1] << "\"\n";
char tk_key[50], tk_value[50];
char mask[] = "%50[^0-9]%50[0-9]";
while ( 2 == fscanf(F, mask, tk_key, tk_value))
std::cout << tk_key << "/" << tk_value << "\n";
fclose(F);
return 0;
}
使用状态机
只有 2 个状态,所以它不是一个花哨的 FSA ;) 状态机很适合表示这种东西,尽管在这里这似乎有点过头了。
#define S_LETTER 0
#define S_DIGIT 1
#include <algorithm>
#include <iostream>
#include <fstream>
using iich = std::istream_iterator<char>;
int main(int argc,char** argv)
{
std::ifstream in_file{argv[1]};
if ( not in_file.good()) return -1;
iich p {in_file}, eofile{};
std::string token{}; // string to build values
char st = S_LETTER; // state value for FSA
std::for_each(p, eofile,
[&token,&st](char ch)
{
char temp = 0;
switch (st)
{
case S_LETTER:
if ((ch >= '0') && (ch <= '9'))
{
std::cout << token << "/";
token = ch;
st = S_DIGIT; // now in number
}
else token += ch; // concat in string
break;
case S_DIGIT:
default:
if ((ch < '0') || (ch > '9'))
{ // is a letter
std::cout << token << "\n";
token = ch;
st = S_LETTER; // now in name
}
else token += ch; // concat in string
break;
}; // switch()
});
std::cout << token << "\n"; // print last token
}
这里我们没有循环。 for_each 从迭代器中获取数据并将其传递给一个函数,该函数将名称和值构建为字符串和couts
输出是一样的
3。一个简单的 FSA 来消费数据
#define S_LETTER 0
#define S_DIGIT 1
#include <iostream>
int main(void)
{
char one[] = "JACK1940383DAVID30284HAROLD68372TROY4392";
char* p = (char*)&one;
char* token = p;
char st = S_LETTER;
char temp = 0;
while (*p != 0)
{
switch (st)
{
case S_LETTER:
if ((*p >= '0') && (*p <= '9'))
{
temp = *p;
*p = 0;
std::cout << token << "/";
*p = temp;
token = p;
st = S_DIGIT; // now in number
}
break;
case S_DIGIT:
default:
if ( (*p < '0') || (*p > '9'))
{ // letter
temp = *p;
*p = 0;
std::cout << token << "\n";
*p = temp;
token = p;
st = S_LETTER; // now in name
}
break;
}; // switch()
p += 1; // next symbol
}; // while()
std::cout << token << "\n"; // print last token
}
这段代码只是使用了一个 C 风格的循环来解析输入数据