Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
B
barrier_gate
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
周彤
barrier_gate
Commits
48497380
Commit
48497380
authored
Dec 19, 2025
by
paopao
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
添加日志
parent
619b0959
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
585 additions
and
36 deletions
+585
-36
CMakeLists.txt
CMakeLists.txt
+1
-1
barrier_gate.cpp
src/barrier_gate.cpp
+23
-3
barrier_gate.hpp
src/barrier_gate.hpp
+5
-32
barrier_gate_log.h
src/barrier_gate_log.h
+556
-0
No files found.
CMakeLists.txt
View file @
48497380
...
...
@@ -74,7 +74,7 @@ install (TARGETS ${PROJECT_NAME}
set
(
MAJOR_VERSION 1
)
set
(
MINOR_VERSION 0
)
set
(
PATCH_VERSION
1
)
set
(
PATCH_VERSION
2
)
set
(
CPACK_PACKAGE_NAME
"ht-
${
PROJECT_NAME
}
"
)
set
(
CPACK_PACKAGE_VERSION_MAJOR
"
${
MAJOR_VERSION
}
"
)
...
...
src/barrier_gate.cpp
View file @
48497380
...
...
@@ -28,7 +28,7 @@ BarrierGateControl::BarrierGateControl(nlohmann::json& config,const std::map<int
,
uart_name_
(
config
[
"uart"
])
,
report_topic_
(
config
[
"report_topic"
])
,
control_topic_
(
config
[
"control_topic"
])
,
numbarrier_config_map
(
numbarrier_info_config_map
)
,
numbarrier_config_map
(
numbarrier_info_config_map
)
,
barrier_gate_Log
(
"Launch.ini"
)
{
init
();
}
...
...
@@ -38,13 +38,28 @@ BarrierGateControl::BarrierGateControl(nlohmann::json& config,const std::map<int
,
uart_name_
(
config
[
"uart"
])
,
report_topic_
(
config
[
"report_topic"
])
,
control_topic_
(
config
[
"control_topic"
])
,
numbarrier_config_map
(
numbarrier_info_config_map
)
,
numbarrier_config_map
(
numbarrier_info_config_map
)
,
barrier_gate_Log
(
"Launch.ini"
)
,
command_
(
command
)
{
RecordTimeLaunch
();
init
();
}
void
BarrierGateControl
::
RecordTimeLaunch
()
{
barrier_gate_Log
.
set_log_file
(
"RecordInfo.log"
);
if
(
!
barrier_gate_Log
.
exists
())
{
std
::
cout
<<
"INI文件不存在,正在创建新文件...
\n
"
;
if
(
!
barrier_gate_Log
.
create
())
{
std
::
cerr
<<
"创建INI文件失败
\n
"
;
return
;
}
}
}
void
BarrierGateControl
::
exec
()
{
__m_running
=
true
;
...
...
@@ -85,6 +100,7 @@ void BarrierGateControl::exec()
buffer
.
resize
(
containts
.
size
());
std
::
copy
(
containts
.
begin
(),
containts
.
end
(),
buffer
.
begin
());
std
::
cout
<<
"publish traffic light states: "
<<
containts
<<
std
::
endl
;
barrier_gate_Log
.
log
(
"publish traffic light states: "
+
containts
);
__m_status_puber
->
publish
(
buffer
);
}
}
...
...
@@ -104,7 +120,7 @@ void BarrierGateControl::exec()
if
(
crc
[
0
]
==
buffer
[
len
-
2
]
&&
crc
[
1
]
==
buffer
[
len
-
1
])
{
std
::
cout
<<
"crc check ok!"
<<
std
::
endl
;
barrier_gate_Log
.
log
(
"crc check ok!"
);
uint8_t
func_code
=
buffer
[
1
];
gate_code
=
(
buffer
[
len
-
4
]
<<
8
|
buffer
[
len
-
3
]);
if
(
func_code
==
0x03
)
...
...
@@ -121,6 +137,7 @@ void BarrierGateControl::exec()
else
{
std
::
cout
<<
"unknown func code: "
<<
(
int
)
func_code
<<
std
::
endl
;
barrier_gate_Log
.
log
(
"unknown func code:"
);
Exc_Barrier
(
0
,
gate_code
);
// 失败
}
}
...
...
@@ -159,6 +176,7 @@ void BarrierGateControl::init()
current_gate_
=
cvt_gate_status
(
command_
);
gate_control
(
0
,
current_gate_
);
std
::
cerr
<<
"init gate_control ..........."
<<
command_
<<
"current_gate_="
<<
current_gate_
<<
std
::
endl
;
barrier_gate_Log
.
log
(
"init gate_control ..........."
+
command_
+
"current_gate_="
+
std
::
to_string
(
current_gate_
));
}
void
BarrierGateControl
::
on_control_request
(
const
mqtt_dataio
::
subscriber_basic
::
DataBuffer
&
msg
)
...
...
@@ -181,6 +199,7 @@ void BarrierGateControl::on_control_request(const mqtt_dataio::subscriber_basic:
gate_control
(
0
,
gate
);
std
::
cout
<<
"change traffic light status from: "
<<
cvt_gate_status
(
current_gate_
)
<<
" to "
<<
cvt_gate_status
(
gate
)
<<
std
::
endl
;
barrier_gate_Log
.
log
(
"change traffic light status from: "
+
cvt_gate_status
(
current_gate_
)
+
" to "
+
cvt_gate_status
(
gate
));
current_gate_
=
gate
;
}
...
...
@@ -209,6 +228,7 @@ void BarrierGateControl::Exc_Barrier(int stateCode,uint16_t changeCode )
current_gate_
=
(
GateState
)
changeCode
;
std
::
string
barrier_gate_status
=
cvt_gate_status
(
changeCode
);
std
::
cout
<<
"gate code: "
<<
(
int
)
changeCode
<<
", barrier gate status: "
<<
barrier_gate_status
<<
std
::
endl
;
barrier_gate_Log
.
log
(
"gate code: "
+
std
::
to_string
((
int
)
changeCode
)
+
", barrier gate status: "
+
barrier_gate_status
);
return
;
}
//成功删除第一个值,取下一个值
...
...
src/barrier_gate.hpp
View file @
48497380
...
...
@@ -6,39 +6,8 @@
#include "uart/uart.hpp"
#include "3th-part/json.hpp"
#include <queue>
#include"barrier_gate_log.h"
struct
traffic_light_config
{
/* data */
uint16_t
id
;
std
::
string
type
;
std
::
vector
<
uint16_t
>
do_addr
;
std
::
vector
<
std
::
string
>
color
;
};
struct
roadside_info_config
{
std
::
string
id
;
std
::
string
topic
;
double
longitude
;
double
latitude
;
double
altitude
;
uint32_t
isLight
;
};
struct
traffic_light_status_config
{
/* data */
uint16_t
id
;
std
::
string
color
;
};
struct
traffic_mode_config
{
uint16_t
id
;
std
::
vector
<
traffic_light_status_config
>
lights
;
};
class
BarrierGateControl
...
...
@@ -90,6 +59,8 @@ private:
void
on_control_request
(
const
mqtt_dataio
::
subscriber_basic
::
DataBuffer
&
msg
);
void
RecordTimeLaunch
();
//记录日志
private
:
bool
__m_running
;
...
...
@@ -97,4 +68,6 @@ private:
uint16_t
__m_offset_do_addr
;
std
::
map
<
int
,
std
::
string
>
numbarrier_config_map
;
std
::
queue
<
BarrierGateControl
::
roadside_info_barrier
>
curExcBarrierQueue
;
Barrier_Gate_Log
barrier_gate_Log
;
//记录日志数据
};
src/barrier_gate_log.h
0 → 100644
View file @
48497380
#pragma once
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <map>
#include <vector>
#include <algorithm>
#include <cctype>
#include <ctime>
#include <iomanip>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <pwd.h>
#include <mutex>
struct
traffic_light_config
{
/* data */
uint16_t
id
;
std
::
string
name
;
std
::
string
type
;
std
::
vector
<
uint16_t
>
do_addr
;
std
::
vector
<
std
::
string
>
color
;
};
struct
roadside_info_config
{
std
::
string
id
;
std
::
string
topic
;
double
longitude
;
double
latitude
;
double
altitude
;
uint32_t
isLight
;
bool
isManualLane
;
uint16_t
lightState
;
};
struct
traffic_light_status_config
{
/* data */
uint16_t
id
;
std
::
string
color
;
};
struct
traffic_mode_config
{
uint16_t
id
;
std
::
vector
<
traffic_light_status_config
>
lights
;
};
// INI 配置文件管理类
class
Barrier_Gate_Log
{
private
:
std
::
string
filename
;
std
::
map
<
std
::
string
,
std
::
map
<
std
::
string
,
std
::
string
>>
data
;
bool
file_exists
=
false
;
std
::
string
log_file
;
// 去除字符串两端的空白字符
static
std
::
string
trim
(
const
std
::
string
&
str
)
{
size_t
start
=
str
.
find_first_not_of
(
"
\t\r\n
"
);
size_t
end
=
str
.
find_last_not_of
(
"
\t\r\n
"
);
if
(
start
==
std
::
string
::
npos
)
return
""
;
return
str
.
substr
(
start
,
end
-
start
+
1
);
}
// 检查字符串是否以指定前缀开头
static
bool
starts_with
(
const
std
::
string
&
str
,
const
std
::
string
&
prefix
)
{
return
str
.
size
()
>=
prefix
.
size
()
&&
str
.
compare
(
0
,
prefix
.
size
(),
prefix
)
==
0
;
}
// 获取当前时间字符串
static
std
::
string
current_time
()
{
auto
now
=
std
::
chrono
::
system_clock
::
now
();
std
::
time_t
now_c
=
std
::
chrono
::
system_clock
::
to_time_t
(
now
);
std
::
tm
now_tm
=
*
std
::
localtime
(
&
now_c
);
std
::
ostringstream
oss
;
oss
<<
std
::
put_time
(
&
now_tm
,
"%Y-%m-%d %H:%M:%S"
);
auto
ms
=
std
::
chrono
::
duration_cast
<
std
::
chrono
::
milliseconds
>
(
now
.
time_since_epoch
())
%
1000
;
oss
<<
'.'
<<
std
::
setfill
(
'0'
)
<<
std
::
setw
(
3
)
<<
ms
.
count
();
return
oss
.
str
();
}
// 确保目录存在
bool
ensure_directory_exists
(
const
std
::
string
&
path
)
{
size_t
pos
=
0
;
std
::
string
dir
;
while
((
pos
=
path
.
find_first_of
(
'/'
,
pos
+
1
))
!=
std
::
string
::
npos
)
{
dir
=
path
.
substr
(
0
,
pos
);
if
(
dir
.
empty
())
continue
;
// 跳过根目录
struct
stat
st
;
if
(
stat
(
dir
.
c_str
(),
&
st
)
!=
0
)
{
// 目录不存在,创建它
if
(
mkdir
(
dir
.
c_str
(),
0755
)
!=
0
&&
errno
!=
EEXIST
)
{
log
(
"创建目录失败: "
+
dir
);
return
false
;
}
}
else
if
(
!
S_ISDIR
(
st
.
st_mode
))
{
log
(
"路径不是目录: "
+
dir
);
return
false
;
}
}
return
true
;
}
// 解析一行INI内容
void
parse_line
(
const
std
::
string
&
line
,
std
::
string
&
current_section
)
{
std
::
string
trimmed
=
trim
(
line
);
// 跳过空行和注释
if
(
trimmed
.
empty
()
||
starts_with
(
trimmed
,
"#"
)
||
starts_with
(
trimmed
,
";"
))
{
return
;
}
// 处理节
if
(
trimmed
.
front
()
==
'['
&&
trimmed
.
back
()
==
']'
)
{
current_section
=
trim
(
trimmed
.
substr
(
1
,
trimmed
.
size
()
-
2
));
return
;
}
// 处理键值对
size_t
pos
=
trimmed
.
find
(
'='
);
if
(
pos
!=
std
::
string
::
npos
)
{
std
::
string
key
=
trim
(
trimmed
.
substr
(
0
,
pos
));
std
::
string
value
=
trim
(
trimmed
.
substr
(
pos
+
1
));
// 处理带引号的值
if
(
!
value
.
empty
()
&&
value
.
front
()
==
'"'
&&
value
.
back
()
==
'"'
)
{
value
=
value
.
substr
(
1
,
value
.
size
()
-
2
);
}
data
[
current_section
][
key
]
=
value
;
}
}
public
:
// 记录日志
void
log
(
const
std
::
string
&
message
)
{
if
(
log_file
.
empty
())
return
;
std
::
ofstream
log_stream
(
log_file
,
std
::
ios
::
app
);
if
(
log_stream
.
is_open
())
{
// 移动指针到文件末尾
log_stream
.
seekp
(
0
,
std
::
ios
::
end
);
// 获取文件大小
long
long
fileSize
=
log_stream
.
tellp
();
if
(
fileSize
>
200
*
1024
*
1024
)
{
log_stream
.
close
();
log_stream
.
clear
();
log_stream
.
open
(
log_file
,
std
::
ios
::
trunc
);
}
log_stream
<<
"["
<<
current_time
()
<<
"] "
<<
message
<<
"
\n
"
;
}
}
// 构造函数
Barrier_Gate_Log
(
const
std
::
string
&
file
)
:
filename
(
file
)
{
struct
stat
st
;
if
(
stat
(
filename
.
c_str
(),
&
st
)
==
0
)
{
file_exists
=
true
;
log
(
"INI文件存在: "
+
filename
);
}
else
{
log
(
"INI文件不存在: "
+
filename
);
}
}
// 设置日志文件
void
set_log_file
(
const
std
::
string
&
inlog
)
{
log_file
=
inlog
;
log
(
"日志文件设置为: "
+
inlog
);
}
// 检查INI文件是否存在
bool
exists
()
const
{
return
file_exists
;
}
// 创建INI文件
bool
create
()
{
if
(
file_exists
)
{
log
(
"INI文件已存在: "
+
filename
);
return
false
;
}
// 确保目录存在
if
(
!
ensure_directory_exists
(
filename
))
{
log
(
"无法创建目录路径: "
+
filename
);
return
false
;
}
std
::
ofstream
file
(
filename
);
if
(
!
file
)
{
log
(
"无法创建INI文件: "
+
filename
+
" - "
);
return
false
;
}
// 写入默认配置
file
<<
"# Linux INI 配置文件 记录一段时间内程序启动次数
\n
"
;
file
<<
"# 创建时间: "
<<
current_time
()
<<
"
\n
"
;
file
<<
"# 格式说明:
\n
"
;
file
<<
"# [Section] 表示配置节
\n
"
;
file
<<
"# key = value 表示键值对
\n
"
;
file
<<
"# 以#或;开头的行是注释
\n\n
"
;
auto
now
=
std
::
chrono
::
system_clock
::
now
();
// 转换为时间戳(毫秒)
uint64_t
timestamp_seconds
=
std
::
chrono
::
duration_cast
<
std
::
chrono
::
milliseconds
>
(
now
.
time_since_epoch
()).
count
();
file
<<
"[General]
\n
"
;
file
<<
"app_name = Light_control
\n
"
;
file
<<
"version = 1.0.0
\n
"
;
file
<<
"LaunchTimes = "
<<
1
<<
"
\n
"
;
file
<<
"LaunchTimestamp = "
<<
timestamp_seconds
<<
"
\n
"
;
file
.
close
();
file_exists
=
true
;
log
(
"INI文件已创建: "
+
filename
);
return
true
;
}
// 加载INI文件
bool
load
()
{
if
(
!
file_exists
)
{
log
(
"INI文件不存在: "
+
filename
);
return
false
;
}
std
::
ifstream
file
(
filename
);
if
(
!
file
)
{
log
(
"无法打开INI文件: "
+
filename
+
" - "
);
return
false
;
}
data
.
clear
();
std
::
string
line
;
std
::
string
current_section
=
"General"
;
while
(
std
::
getline
(
file
,
line
))
{
parse_line
(
line
,
current_section
);
std
::
cout
<<
"getline...
\n
"
;
}
file
.
close
();
log
(
"INI文件已加载: "
+
filename
);
return
true
;
}
// 保存INI文件
bool
save
()
{
if
(
!
file_exists
)
{
log
(
"INI文件不存在: "
+
filename
);
return
false
;
}
// 备份原文件
std
::
string
backup
=
filename
+
".bak"
;
if
(
std
::
rename
(
filename
.
c_str
(),
backup
.
c_str
())
!=
0
)
{
log
(
"创建备份失败: "
);
}
else
{
log
(
"已创建备份: "
+
backup
);
}
std
::
ofstream
file
(
filename
);
if
(
!
file
)
{
log
(
"无法写入INI文件: "
+
filename
+
" - "
);
// 恢复备份
std
::
rename
(
backup
.
c_str
(),
filename
.
c_str
());
return
false
;
}
file
<<
"# Linux INI 配置文件
\n
"
;
file
<<
"# 最后修改时间: "
<<
current_time
()
<<
"
\n
"
;
file
<<
"# 用户: "
<<
getlogin
()
<<
"
\n\n
"
;
for
(
const
auto
&
section
:
data
)
{
file
<<
"["
<<
section
.
first
<<
"]
\n
"
;
for
(
const
auto
&
key_value
:
section
.
second
)
{
file
<<
key_value
.
first
<<
" = "
<<
key_value
.
second
<<
"
\n
"
;
}
file
<<
"
\n
"
;
}
file
.
close
();
log
(
"INI文件已保存: "
+
filename
);
return
true
;
}
// 获取配置值
std
::
string
get_value
(
const
std
::
string
&
section
,
const
std
::
string
&
key
,
const
std
::
string
&
default_value
=
""
)
{
auto
sec_it
=
data
.
find
(
section
);
if
(
sec_it
==
data
.
end
())
{
log
(
"获取配置值失败 - 节不存在: ["
+
section
+
"] "
+
key
);
return
default_value
;
}
auto
key_it
=
sec_it
->
second
.
find
(
key
);
if
(
key_it
==
sec_it
->
second
.
end
())
{
log
(
"获取配置值失败 - 键不存在: ["
+
section
+
"] "
+
key
);
return
default_value
;
}
log
(
"获取配置值: ["
+
section
+
"] "
+
key
+
" = "
+
key_it
->
second
);
return
key_it
->
second
;
}
// 获取整数值
uint64_t
get_int
(
const
std
::
string
&
section
,
const
std
::
string
&
key
,
int
default_value
=
0
)
{
std
::
string
value
=
get_value
(
section
,
key
,
""
);
if
(
value
.
empty
())
return
default_value
;
try
{
//return std::stoi(value);
char
*
endptr
=
nullptr
;
errno
=
0
;
// 重置错误标志
unsigned
long
long
intvalue
=
std
::
strtoull
(
value
.
c_str
(),
&
endptr
,
10
);
return
static_cast
<
uint64_t
>
(
intvalue
);
}
catch
(...)
{
log
(
"转换整数值失败: ["
+
section
+
"] "
+
key
+
" = "
+
value
);
return
default_value
;
}
}
// 获取浮点数值
double
get_double
(
const
std
::
string
&
section
,
const
std
::
string
&
key
,
double
default_value
=
0
.
0
)
{
std
::
string
value
=
get_value
(
section
,
key
,
""
);
if
(
value
.
empty
())
return
default_value
;
try
{
return
std
::
stod
(
value
);
}
catch
(...)
{
log
(
"转换浮点数值失败: ["
+
section
+
"] "
+
key
+
" = "
+
value
);
return
default_value
;
}
}
// 获取布尔值
bool
get_bool
(
const
std
::
string
&
section
,
const
std
::
string
&
key
,
bool
default_value
=
false
)
{
std
::
string
value
=
get_value
(
section
,
key
,
""
);
if
(
value
.
empty
())
return
default_value
;
// 转换为小写比较
std
::
string
lower_value
;
std
::
transform
(
value
.
begin
(),
value
.
end
(),
std
::
back_inserter
(
lower_value
),
[](
unsigned
char
c
)
{
return
std
::
tolower
(
c
);
});
if
(
lower_value
==
"true"
||
lower_value
==
"yes"
||
lower_value
==
"1"
)
{
return
true
;
}
else
if
(
lower_value
==
"false"
||
lower_value
==
"no"
||
lower_value
==
"0"
)
{
return
false
;
}
else
{
log
(
"转换布尔值失败: ["
+
section
+
"] "
+
key
+
" = "
+
value
);
return
default_value
;
}
}
// 设置配置值
void
set_value
(
const
std
::
string
&
section
,
const
std
::
string
&
key
,
const
std
::
string
&
value
)
{
// std::lock_guard<std::mutex> lock(mtx);
std
::
string
old_value
=
get_value
(
section
,
key
,
""
);
data
[
section
][
key
]
=
value
;
log
(
"设置配置值: ["
+
section
+
"] "
+
key
+
" = "
+
value
+
" (原值: "
+
old_value
+
")"
);
}
// 设置整数值
void
set_int
(
const
std
::
string
&
section
,
const
std
::
string
&
key
,
uint64_t
value
)
{
set_value
(
section
,
key
,
std
::
to_string
(
value
));
}
// 设置浮点数值
void
set_double
(
const
std
::
string
&
section
,
const
std
::
string
&
key
,
double
value
)
{
set_value
(
section
,
key
,
std
::
to_string
(
value
));
}
// 设置布尔值
void
set_bool
(
const
std
::
string
&
section
,
const
std
::
string
&
key
,
bool
value
)
{
set_value
(
section
,
key
,
value
?
"true"
:
"false"
);
}
// 删除配置项
bool
remove_key
(
const
std
::
string
&
section
,
const
std
::
string
&
key
)
{
auto
sec_it
=
data
.
find
(
section
);
if
(
sec_it
==
data
.
end
())
{
log
(
"删除配置项失败 - 节不存在: ["
+
section
+
"] "
+
key
);
return
false
;
}
if
(
sec_it
->
second
.
erase
(
key
)
>
0
)
{
log
(
"已删除配置项: ["
+
section
+
"] "
+
key
);
return
true
;
}
log
(
"删除配置项失败 - 键不存在: ["
+
section
+
"] "
+
key
);
return
false
;
}
// 删除配置节
bool
remove_section
(
const
std
::
string
&
section
)
{
if
(
data
.
erase
(
section
)
>
0
)
{
log
(
"已删除配置节: ["
+
section
+
"]"
);
return
true
;
}
log
(
"删除配置节失败 - 节不存在: ["
+
section
+
"]"
);
return
false
;
}
// 获取所有配置节
std
::
vector
<
std
::
string
>
get_sections
()
{
std
::
vector
<
std
::
string
>
sections
;
for
(
const
auto
&
section
:
data
)
{
sections
.
push_back
(
section
.
first
);
}
return
sections
;
}
// 获取指定节的所有键
std
::
vector
<
std
::
string
>
get_keys
(
const
std
::
string
&
section
)
{
std
::
vector
<
std
::
string
>
keys
;
auto
sec_it
=
data
.
find
(
section
);
if
(
sec_it
!=
data
.
end
())
{
for
(
const
auto
&
key_value
:
sec_it
->
second
)
{
keys
.
push_back
(
key_value
.
first
);
}
}
return
keys
;
}
// 检查配置节是否存在
bool
section_exists
(
const
std
::
string
&
section
)
{
return
data
.
find
(
section
)
!=
data
.
end
();
}
// 检查配置项是否存在
bool
key_exists
(
const
std
::
string
&
section
,
const
std
::
string
&
key
)
{
auto
sec_it
=
data
.
find
(
section
);
if
(
sec_it
==
data
.
end
())
return
false
;
return
sec_it
->
second
.
find
(
key
)
!=
sec_it
->
second
.
end
();
}
// 显示所有配置
void
display
()
{
std
::
cout
<<
"
\n
INI 文件内容 ("
<<
filename
<<
"):
\n
"
;
std
::
cout
<<
"========================================
\n
"
;
for
(
const
auto
&
section
:
data
)
{
std
::
cout
<<
"["
<<
section
.
first
<<
"]
\n
"
;
for
(
const
auto
&
key_value
:
section
.
second
)
{
std
::
cout
<<
" "
<<
key_value
.
first
<<
" = "
<<
key_value
.
second
<<
"
\n
"
;
}
std
::
cout
<<
"
\n
"
;
}
std
::
cout
<<
"========================================
\n
"
;
log
(
"显示INI文件内容"
);
}
};
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment