当前位置:   article > 正文

C语言函数库查询系统(ACCESS)_access if instr()>0

access if instr()>0

这个主要使用ACCESS来进行制作,可以将C语言的函数、全局变量、宏、联合、结构、枚举等类型的字符串分类储存起来,能使用窗体查询这里里面的函数或者宏,也可以用来查看某个函数属于哪个头文件,比如printf()函数:

当然,要是人工一个一个的输函数,还不得累死,因此使用VBA制作了简单的程序,可以从语言的头文件或者源文件自动识别出函数、全局变量、结构、宏、联合、枚举等,然后添加到表中,不过技术能力有限,还有BUG,识别错误,或者报告文件导入失败其实已经成功是常有的事,目前只能作为一个辅助工具来使用。当程序写大了,或者在看不知名的代码,可以使用这个工具导入一下,就可以看到这个文件包含哪些东西。使用效果如图,这里面已经导入了几个C语言标准库的头文件:

 

 

github地址:https://github.com/lindorx/Cfunlibsearch

VB忘很久了,所以代码写的很乱,不算注释空行大概470多行,VBA的代码:

  1. Option Compare Database
  2. Public depth As Integer '记录当前代码的嵌套深度
  3. Public ann As Boolean '记录当前代码书否属于多行注释
  4. Public num As Integer '记录a字符串数组的大小
  5. Public 所属文件 As String '储存当前正在处理的文件名
  6. Public line As Long '记录当前所在行
  7. Public sql As String '储存要执行的DQL语句
  8. Public headfile As String '储存当前文件引用到的头文件
  9. Public fnum As Long '记录函数数量
  10. Public vnum As Long '记录变量数量
  11. Public model As Integer '记录当前模式,1:检索标准库,2:导入文件
  12. Private Sub Form_Load()
  13. Label0.Caption = "文件路径:"
  14. command0.Caption = "执行"
  15. model = 2
  16. 加入.Visible = False
  17. End Sub
  18. Private Sub 检索标准库_Click()
  19. Label0.Caption = "输入查询的函数或宏:"
  20. command0.Caption = "查询"
  21. model = 1
  22. End Sub
  23. Private Sub 加入_Click()
  24. Text0.SetFocus '将焦点移到文本框,就可以隐藏控件本身
  25. 用户确认 = MsgBox("是否加入?", vbYesNo, "warring")
  26. If 用户确认 = vbNo Then GoTo 加入_End
  27. If standlib() Then
  28. MsgBox "导入完成"
  29. Else: MsgBox "导入失败"
  30. End If
  31. 加入_End:
  32. 加入.Visible = False
  33. End Sub
  34. Private Sub command0_Click()
  35. If model = 1 Then '判断当前模式,1为查询标准库,2为导入文件
  36. Dim db
  37. Dim 标准库 As Recordset
  38. Dim 找到 As Boolean '找到函数名或者宏名标志
  39. 找到 = False
  40. Set db = CurrentDb '令db指向当前的数据库
  41. Set 标准库 = db.OpenRecordset("select * from 标准库") '通过SQL语句获得表
  42. '从text0读取要查询的函数名或宏名
  43. s = Text0.value
  44. If 标准库.EOF Then Exit Sub '判断当前表是否为空
  45. 标准库.MoveFirst '将表定位到第一行
  46. Do While Not 标准库.EOF '遍历表,进行查询
  47. temp = 标准库.Fields("函数名")
  48. If IsNull(temp) Then GoTo l1 '判断该表项是否为空
  49. 函数名 = CStr(temp)
  50. If 函数名 = s Then
  51. 找到 = True
  52. Text1.value = 函数名
  53. Text2.value = CStr(标准库.Fields("函数参数"))
  54. Text5.value = CStr(标准库.Fields("文件名"))
  55. Text3.value = ""
  56. Text4.value = ""
  57. End If
  58. l1:
  59. 标准库.MoveNext '移动到下一行
  60. Loop
  61. If Not 找到 Then
  62. 标准库.MoveFirst
  63. Do While Not 标准库.EOF
  64. On Error GoTo l2
  65. temp = 标准库.Fields("宏名")
  66. If IsNull(temp) Then GoTo l2
  67. 宏名 = CStr(temp)
  68. If 宏名 = s Then
  69. 找到 = True
  70. Text3.value = 宏名
  71. On Error GoTo nodef
  72. Text4.value = CStr(标准库.Fields("宏定义"))
  73. Text5.value = CStr(标准库.Fields("文件名"))
  74. Text1.value = ""
  75. Text2.value = ""
  76. End If
  77. l2:
  78. 标准库.MoveNext
  79. Loop
  80. End If
  81. 标准库.Close
  82. If Not 找到 Then
  83. Text1.value = ""
  84. Text2.value = ""
  85. Text3.value = ""
  86. Text5.value = ""
  87. nodef:
  88. Text4.value = ""
  89. End If
  90. Exit Sub
  91. ElseIf model = 2 Then
  92. Dim filename As String
  93. If IsNull(Text0.value) Then Exit Sub
  94. filename = Text0.value
  95. If filename <> "" And filename <> "输入要读取的文件路径" Then filectrl (filename)
  96. model = 2
  97. End If
  98. End Sub
  99. Private Sub Text0_GotFocus()
  100. Text0.Text = ""
  101. End Sub
  102. Private Sub Text0_LostFocus()
  103. If Text0.Text = "" And model <> 1 Then Text0.Text = "输入要读取的文件路径"
  104. End Sub
  105. Private Sub 读取文件_Click()
  106. Label0.Caption = "文件路径:"
  107. command0.Caption = "执行"
  108. model = 2
  109. End Sub
  110. Function filectrl(filename As String) As Boolean
  111. filectrl = False
  112. Dim buf As String '储存截取出的字符串
  113. Dim strstart As Integer '记录字符串的起始位置
  114. Dim strend As Integer '记录字符串的结束位置
  115. Dim i As Integer '遍历字符串
  116. Dim length As Integer '记录字符串长度
  117. Dim ann As Boolean '记录多行注释,当目前内容是注释时,设为真
  118. depth = 0
  119. ann = False
  120. line = 0
  121. is_struct_union_equm = False
  122. headfile = ""
  123. fnum = 0
  124. vnum = 0
  125. 存在花括号 = False
  126. DoCmd.SetWarnings False '关掉弹窗警告
  127. '提出文件名
  128. 最后一个分割线位置 = InStrRev(filename, "\", Len(filename))
  129. 所属文件 = Mid(filename, 最后一个分割线位置 + 1, Len(filename) - 最后一个分割线位置)
  130. On Error GoTo ferr '如果读取错误,就跳转到ferr这里
  131. Open filename For Input As #1
  132. Do While Not EOF(1) '判断是否到达文件尾
  133. Line Input #1, buf '读取一行字符串到buf
  134. line = line + 1
  135. '去除注释
  136. buf = subcomment(buf)
  137. If buf = "" Then GoTo donext
  138. buf = Replace(buf, """", """""")
  139. '判断宏
  140. If Mid(buf, 1, 1) = "#" Then
  141. If cdefine(buf) Then GoTo donext
  142. If chead(buf) Then GoTo donext
  143. End If
  144. 左花括号 = InStr(1, buf, "{")
  145. 右花括号 = InStr(1, buf, "}")
  146. If 左花括号 > 0 And 右花括号 = 0 Then 存在花括号 = True
  147. '将结构这样带有定义的关键字整体放到一行
  148. If (InStr(1, buf, "struct") > 0 Or InStr(1, buf, "union") > 0 Or InStr(1, buf, "enum") > 0) And 存在花括号 Then
  149. is_struct_union_equm = True
  150. Do While 存在花括号 And Not EOF(1)
  151. Line Input #1, s
  152. line = line + 1
  153. If InStr(1, s, "}") > 0 Then
  154. 存在花括号 = False
  155. buf = buf + s
  156. Else
  157. buf = buf + s
  158. End If
  159. Loop
  160. End If
  161. '判断是否属于结构,联合,枚举等类型
  162. If is_struct_union_equm Then
  163. cblock (buf)
  164. is_struct_union_equm = False '重新置位,防止下一次循环错误使用
  165. GoTo donext
  166. End If
  167. '判断函数
  168. If fun(buf) Then
  169. GoTo donext
  170. '判断变量
  171. ElseIf cvalue(splitStr(buf)) Then
  172. GoTo donext
  173. End If
  174. If 左花括号 > 0 Then depth = depth + 1
  175. If 右花括号 > 0 Then depth = depth - 1
  176. If depth < 0 Then Exit Do
  177. donext:
  178. Loop
  179. Close #1
  180. 文件类型 = "未知"
  181. 句号未知 = InStr(2, 所属文件, ".")
  182. If 句号位置 > 0 Then
  183. 后缀名 = Mid(所属文件, 句号位置, Len(所属文件) - 句号位置)
  184. If 后缀名 = "h" Or 后缀名 = "H" Then
  185. 文件类型 = "头文件"
  186. ElseIf 后缀名 = "c" Or 后缀名 = "C" Then
  187. 文件类型 = "源文件"
  188. End If
  189. End If
  190. sql = "insert into C代码表(文件名,文件类型,代码行数,函数数量,变量数量,引用到的头文件) values(""" _
  191. + 所属文件 + """,""" + 文件类型 + """," + str(line) + "," + str(fnum) + "," + str(vnum) + ",""" + headfile + """);"
  192. 'MsgBox sql
  193. DoCmd.RunSQL sql
  194. MsgBox "文件导入完成"
  195. 加入.Visible = True
  196. filectrl = True
  197. Exit Function
  198. ferr: '文件读取错误
  199. Close #1
  200. MsgBox "文件路径错误"
  201. End Function
  202. '函数处理
  203. Function fun(buf)
  204. DimAs Boolean
  205. 右 = False
  206. fun = False
  207. '查找括号,如果存在括号,则将括号前以非英文字符、数字、下划线划分的字符串提出
  208. length = InStr(1, buf, "(")
  209. 左花括号 = InStr(1, buf, "{")
  210. 右花括号 = InStr(1, buf, "}")
  211. 等于号 = InStr(1, buf, "=")
  212. If 等于号 <> 0 Then GoTo exitfun
  213. If length = 0 Then GoTo exitfun
  214. If 左花括号 > 0 And 左花括号 < length Then
  215. depth = depth + 1
  216. Exit Function
  217. End If
  218. If 右花括号 > 0 And 右花括号 < length Then
  219. depth = depth - 1
  220. 右 = True
  221. End If
  222. strend = length
  223. If strend > 0 And depth = 0 Then '存在括号且嵌套深度为0
  224. a = splitStr(buf)
  225. 函数类型 = ""
  226. For i = 1 To num
  227. t = InStr(1, a(i), "(")
  228. If t > 0 Then
  229. If t > 1 Then
  230. 函数名 = Mid(a(i), 1, t - 1)
  231. For j = 1 To i - 1
  232. 函数类型 = 函数类型 + a(j) + " "
  233. Next
  234. Else
  235. 函数名 = a(i - 1)
  236. For j = 1 To i - 2
  237. 函数类型 = 函数类型 + a(j) + " "
  238. Next
  239. End If
  240. Exit For
  241. End If
  242. Next
  243. '取出函数参数
  244. t = InStr(length, buf, ")")
  245. If t <> 0 Then
  246. 函数参数 = Mid(buf, length, t - length + 1)
  247. 'MsgBox "函数参数:" + 函数参数
  248. End If
  249. End If
  250. If 函数名 <> "" Then
  251. fun = True
  252. Else
  253. Exit Function
  254. End If
  255. sql = "insert into 函数(函数名,类型,参数,所在行,所属文件,引用到的函数,定义) values(""" + _
  256. 函数名 + """,""" + 函数类型 + """,""" + 函数参数 + """," + str(line) + ",""" + 所属文件 + _
  257. """,""" + "未知" + """,""" + "未知" + """);"
  258. 'MsgBox sql
  259. DoCmd.RunSQL sql
  260. fnum = fnum + 1
  261. exitfun:
  262. If 左花括号 > 0 Then depth = depth + 1
  263. If 右花括号 > 0 And NotThen depth = depth - 1
  264. End Function
  265. '去除注释
  266. Function subcomment(buf)
  267. Dim length As Integer
  268. Dim strstart As Integer
  269. Dim strend As Integer
  270. strstart = 1
  271. strend = -1
  272. '将所有换行符替换为空格
  273. length = InStr(1, buf, "*/")
  274. If length > 0 Then
  275. ann = False
  276. strstart = length + 2 'i指向有效的字符串位置
  277. End If
  278. If ann Then
  279. subcomment = ""
  280. Exit Function
  281. End If
  282. If strstart > Len(buf) Then
  283. subcomment = ""
  284. Exit Function
  285. End If
  286. length = InStr(strstart, buf, "/*")
  287. If length > 0 Then
  288. strend = length - 1
  289. ann = True
  290. End If
  291. length = InStr(strstart, buf, "//")
  292. If length > 0 Then
  293. strend = length - 1
  294. End If
  295. If strend = -1 Then
  296. strend = Len(buf)
  297. ElseIf strend = 0 Then
  298. subcomment = ""
  299. Exit Function
  300. End If
  301. '通过strstart和strend两个下标值确定非注释字符串的位置,取出字符串
  302. buf = Mid(buf, strstart, strend - strstart + 1)
  303. '去除字符串左右两边的多余空格,制表符
  304. buf = Replace(buf, vbTab, " ") '将制表符全部替换为空格
  305. buf = Trim(buf)
  306. subcomment = buf
  307. End Function
  308. '宏处理
  309. Function cdefine(buf)
  310. cdefine = False
  311. 第一个空格的位置 = InStr(1, buf, " ")
  312. If 第一个空格的位置 < 2 Then
  313. Exit Function
  314. End If
  315. 第一个字符串 = Mid(buf, 2, 第一个空格的位置 - 2)
  316. If 第一个字符串 = "define" Then
  317. 第二个空格的位置 = InStr((第一个空格的位置 + 1), buf, " ")
  318. length = 0
  319. If 第二个空格的位置 = 0 Then
  320. If Len(buf) > 第一个空格的位置 Then
  321. length = Len(buf) - 第一个空格的位置
  322. Else
  323. Exit Function
  324. End If
  325. Else
  326. length = 第二个空格的位置 - 第一个空格的位置 - 1
  327. End If
  328. 第二个字符串 = Mid(buf, 第一个空格的位置 + 1, length)
  329. Else
  330. Exit Function
  331. End If
  332. If 第二个空格的位置 > 0 Then
  333. 第三个字符串 = Mid(buf, 第二个空格的位置, Len(buf) + 1 - 第二个空格的位置)
  334. Else
  335. 第三个字符串 = ""
  336. End If
  337. 'MsgBox "宏:" + 第一个字符串
  338. 'MsgBox "宏名:" + 第二个字符串
  339. 'MsgBox "宏定义:" + 第三个字符串
  340. sql = "insert into 宏(宏名,值,所在行,所属文件) values(""" + Trim(第二个字符串) + """,""" + Trim(第三个字符串) + """," + str(line) + ",""" + 所属文件 + """);"
  341. 'MsgBox sql
  342. DoCmd.RunSQL sql
  343. cdefine = True
  344. End Function
  345. '全局变量处理,函数内部的变量识别复杂,而且通常情况没有必要,因此没有实现
  346. Function cvalue(a)
  347. Dim i As Integer
  348. cvalue = False
  349. 类型 = ""
  350. 变量名 = ""
  351. 值 = ""
  352. If depth <> 0 Then
  353. Exit Function
  354. End If
  355. '遍历a,查看是否有=,如果有说明该变量被赋值
  356. 找到等于号 = False
  357. For i = 1 To num
  358. 等于号位置 = InStr(1, a(i), "=")
  359. If 等于号位置 > 0 Then
  360. 找到等于号 = True
  361. Exit For
  362. End If
  363. Next
  364. If 找到等于号 Then
  365. For j = 1 To i - 2
  366. 类型 = 类型 + a(j) + " "
  367. Next
  368. If 等于号位置 = 1 Then '说明该a(i)第一个字符为等于号
  369. 变量名 = a(i - 1)
  370. 值 = a(num)
  371. Else
  372. 变量名 = Mid(a(i), 1, 等于号位置 - 1)
  373. 类型 = 类型 + a(i - 1) + " "
  374. 值 = Mid(a(i), 等于号位置 + 1, Len(a(i)) - 等于号位置)
  375. End If
  376. Else
  377. 变量名 = a(num)
  378. For j = 1 To num - 1
  379. 类型 = 类型 + a(j) + " "
  380. Next
  381. End If
  382. 'MsgBox 变量名
  383. 'MsgBox 类型
  384. 'MsgBox 值
  385. cvalue = True
  386. sql = "insert into 变量(变量名,类型,初始值,所在行,所属文件) values(""" + 变量名 + """,""" + 类型 + """,""" + 值 + """," + str(line) + ",""" + 所属文件 + """);"
  387. DoCmd.RunSQL sql
  388. vnum = vnum + 1
  389. End Function
  390. '按空格分割字符串,返回一个字符串数组,这个数组的长度由全集变量num说明
  391. Function splitStr(codestr)
  392. Dim a() As String
  393. num = 1
  394. Dim i As Integer
  395. i = 1
  396. Do While i < Len(codestr)
  397. b = InStr(i, codestr, " ")
  398. If b <> 0 Then
  399. If b > i Then
  400. ReDim Preserve a(num)
  401. a(num) = Trim(Mid(codestr, i, b - i))
  402. num = num + 1
  403. End If
  404. i = b + 1
  405. Else
  406. Exit Do
  407. End If
  408. Loop
  409. '还有最后一个字符串可能没有读入
  410. ReDim Preserve a(num)
  411. a(num) = Trim(Mid(codestr, i, Len(codestr) - i))
  412. splitStr = a
  413. End Function
  414. '对结构,联合,枚举的处理
  415. Function cblock(buf)
  416. cblock = False
  417. 左花括号 = InStr(1, buf, "{")
  418. 右花括号 = InStr(1, buf, "}")
  419. If 左花括号 = 0 Or 右花括号 = 0 Then
  420. Exit Function
  421. End If
  422. 's储存关键字名
  423. s = Trim(Mid(buf, 1, 左花括号 - 1))
  424. 定义 = Trim(Mid(buf, 左花括号, 右花括号 - 左花括号 + 1))
  425. 别名 = Trim(Mid(buf, 右花括号 + 1, Len(buf) - 右花括号 - 1))
  426. If InStr(1, s, "struct") > 0 Then
  427. sql = "insert into 结构(结构名,定义,别名,所在行,所属文件) values(""" + s + """,""" + 定义 + """,""" + 别名 + """," + str(line) + ",""" + 所属文件 + """);"
  428. DoCmd.RunSQL sql
  429. ElseIf InStr(1, s, "union") > 0 Then
  430. sql = "insert into 联合体(联合体名,定义,别名,所在行,所属文件) values(""" + s + """,""" + 定义 + """,""" + 别名 + """," + str(line) + ",""" + 所属文件 + """);"
  431. DoCmd.RunSQL sql
  432. ElseIf InStr(1, s, "enum") > 0 Then
  433. sql = "insert into 枚举(枚举名,定义,别名,所在行,所属文件) values(""" + s + """,""" + 定义 + """,""" + 别名 + """," + str(line) + ",""" + 所属文件 + """);"
  434. DoCmd.RunSQL sql
  435. Else
  436. Exit Function
  437. End If
  438. 'MsgBox "名:" + s
  439. 'MsgBox "定义:" + 定义
  440. 'MsgBox "别名:" + 别名
  441. cblock = True
  442. End Function
  443. '处理头文件
  444. Function chead(buf)
  445. chead = False
  446. inc = Mid(buf, 2, 7)
  447. If inc = "include" Then
  448. '读取后面括号或者引号之间的文件名
  449. 左 = InStr(9, buf, "<")
  450. If 左 > 0 Then
  451. 右 = InStr(10, buf, ">")
  452. If 右 = 0 Then
  453. Exit Function
  454. End If
  455. headfile = headfile + Mid(buf, 左, 右 - 左 + 1) + ";"
  456. Else
  457. 左 = InStr(9, buf, """")
  458. 右 = InStr(10, buf, """")
  459. If 左 = 0 Or 右 = 0 Then
  460. Exit Function
  461. End If
  462. headfile = headfile + Mid(buf, 左, 右 - 左 + 1) + ";"
  463. End If
  464. End If
  465. chead = True
  466. End Function
  467. '标准库操作,将函数表和宏表合并到标准库表
  468. Function standlib() As Boolean
  469. standlib = False
  470. 函数表可用 = True
  471. 宏表可用 = True
  472. Dim db
  473. Dim 宏表 As Recordset
  474. Dim 函数表 As Recordset
  475. Dim s As String '储存读取标识符
  476. Set db = CurrentDb '设定为当前数据库
  477. Set 宏表 = db.OpenRecordset("select * from 宏")
  478. Set 函数表 = db.OpenRecordset("select * from 函数")
  479. If 宏表.EOF And 函数表.EOF Then Exit Function
  480. If 宏表.EOF Then
  481. 宏表可用 = False
  482. Else: 宏表.MoveFirst
  483. End If
  484. If 函数表.EOF Then
  485. 函数表可用 = False
  486. Else: 函数表.MoveFirst
  487. End If
  488. Do While (Not 宏表.EOF) Or (Not 函数表.EOF)
  489. If Not 宏表.EOF And 宏表可用 Then
  490. On Error GoTo fnext '错误处理,一般情况是读取到了空表项,此时利用goto来跳转
  491. 宏名 = CStr(宏表.Fields("宏名"))
  492. On Error GoTo fnext
  493. 宏定义 = Replace(CStr(宏表.Fields("值")), """", """""")
  494. On Error GoTo fnext
  495. 文件名 = CStr(宏表.Fields("所属文件"))
  496. sql = "insert into 标准库(宏名,宏定义,文件名) values(""" + 宏名 + """,""" _
  497. + 宏定义 + """,""" + 文件名 + """);"
  498. On Error GoTo fnext
  499. DoCmd.RunSQL sql
  500. standlib = True
  501. fnext:
  502. 宏表.MoveNext
  503. End If
  504. If Not 函数表.EOF And 函数表可用 Then
  505. On Error GoTo anext
  506. 函数名 = CStr(函数表.Fields("函数名"))
  507. On Error GoTo anext
  508. 函数参数 = CStr(函数表.Fields("参数"))
  509. On Error GoTo anext
  510. 文件名 = CStr(函数表.Fields("所属文件"))
  511. sql = "insert into 标准库(函数名,函数参数,文件名) values(""" + 函数名 + """,""" _
  512. + 函数参数 + """,""" + 文件名 + """);"
  513. On Error GoTo anext
  514. DoCmd.RunSQL sql
  515. standlib = True
  516. anext:
  517. 函数表.MoveNext
  518. End If
  519. Loop
  520. 宏表.Close '关闭表
  521. 函数表.Close
  522. End Function

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/blog/article/detail/84862
推荐阅读
相关标签
  

闽ICP备14008679号