Merge branch 'master' into 杨腾泽

杨腾泽
yangtengze 2 years ago
commit e33071f8ee

@ -0,0 +1,277 @@
<mxfile host="65bd71144e">
<diagram id="0iwV3ipOlTaEYRU5HPaa" name="Page-1">
<mxGraphModel dx="1824" dy="1701" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<mxCell id="5" value="" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;sketch=1;curveFitting=1;jiggle=2;fontFamily=Helvetica;fontStyle=1" parent="1" source="3" target="4" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="17" value="" style="edgeStyle=none;html=1;fillColor=#60a917;strokeColor=#2D7600;sketch=1;curveFitting=1;jiggle=2;fontFamily=Helvetica;fontStyle=1" parent="1" source="3" target="4" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="18" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;fillColor=#60a917;strokeColor=#2D7600;sketch=1;curveFitting=1;jiggle=2;fontFamily=Helvetica;fontStyle=1" parent="1" source="3" target="7" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="280" y="320" as="targetPoint"/>
<Array as="points">
<mxPoint x="280" y="320"/>
<mxPoint x="280" y="180"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="19" style="edgeStyle=none;html=1;entryX=1;entryY=0.5;entryDx=0;entryDy=0;fillColor=#60a917;strokeColor=#2D7600;sketch=1;curveFitting=1;jiggle=2;fontFamily=Helvetica;fontStyle=1" parent="1" source="3" target="13" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="280" y="320"/>
<mxPoint x="280" y="460"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="20" style="edgeStyle=none;html=1;entryX=1;entryY=0.5;entryDx=0;entryDy=0;fillColor=#60a917;strokeColor=#2D7600;sketch=1;curveFitting=1;jiggle=2;fontFamily=Helvetica;fontStyle=1" parent="1" source="3" target="15" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="280" y="320"/>
<mxPoint x="280" y="600"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="21" style="edgeStyle=none;html=1;entryX=1;entryY=0.5;entryDx=0;entryDy=0;fillColor=#60a917;strokeColor=#2D7600;sketch=1;curveFitting=1;jiggle=2;fontFamily=Helvetica;fontStyle=1" parent="1" source="3" target="10" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="280" y="320"/>
<mxPoint x="280" y="40"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="65" style="edgeStyle=none;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;fillColor=#d80073;strokeColor=#4C0099;sketch=1;curveFitting=1;jiggle=2;fontFamily=Helvetica;fontStyle=1;strokeWidth=3;" parent="1" source="3" target="49" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="67" style="edgeStyle=none;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;fillColor=#d80073;strokeColor=#4C0099;sketch=1;curveFitting=1;jiggle=2;fontFamily=Helvetica;fontStyle=1;strokeWidth=3;" parent="1" source="3" target="50" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="530" y="320" as="targetPoint"/>
<Array as="points">
<mxPoint x="520" y="320"/>
<mxPoint x="520" y="190"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="68" style="edgeStyle=none;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;fillColor=#d80073;strokeColor=#4C0099;sketch=1;curveFitting=1;jiggle=2;fontFamily=Helvetica;fontStyle=1;strokeWidth=3;" parent="1" source="3" target="52" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="520" y="320"/>
<mxPoint x="520" y="50"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="69" style="edgeStyle=none;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;fillColor=#d80073;strokeColor=#4C0099;sketch=1;curveFitting=1;jiggle=2;fontFamily=Helvetica;fontStyle=1;strokeWidth=3;" parent="1" source="3" target="58" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="520" y="320"/>
<mxPoint x="520" y="470"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="70" style="edgeStyle=none;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;fillColor=#d80073;strokeColor=#4C0099;sketch=1;curveFitting=1;jiggle=2;fontFamily=Helvetica;fontStyle=1;strokeWidth=3;" parent="1" source="3" target="60" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="520" y="320"/>
<mxPoint x="520" y="610"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="71" style="edgeStyle=none;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;fillColor=#d80073;strokeColor=#4C0099;sketch=1;curveFitting=1;jiggle=2;fontFamily=Helvetica;fontStyle=1;strokeWidth=3;" parent="1" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="471" y="320" as="sourcePoint"/>
<mxPoint x="581" y="750" as="targetPoint"/>
<Array as="points">
<mxPoint x="521" y="320"/>
<mxPoint x="521" y="750"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="72" style="edgeStyle=none;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;fillColor=#d80073;strokeColor=#4C0099;sketch=1;curveFitting=1;jiggle=2;fontFamily=Helvetica;fontStyle=1;strokeWidth=3;" parent="1" source="3" target="54" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="520" y="320"/>
<mxPoint x="520" y="-90"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="73" style="edgeStyle=none;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;fillColor=#6a00ff;strokeColor=#4C0099;sketch=1;curveFitting=1;jiggle=2;fontFamily=Helvetica;fontStyle=1;strokeWidth=3;" parent="1" source="3" target="56" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="520" y="320"/>
<mxPoint x="520" y="-230"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="3" value="&lt;h1 style=&quot;font-size: 30px;&quot;&gt;main&lt;/h1&gt;" style="rounded=0;whiteSpace=wrap;html=1;sketch=1;curveFitting=1;jiggle=2;fontFamily=Helvetica;fontStyle=1;fontSize=30;" parent="1" vertex="1">
<mxGeometry x="350" y="290" width="120" height="60" as="geometry"/>
</mxCell>
<mxCell id="4" value="&lt;h2&gt;make_choice&lt;/h2&gt;" style="rounded=0;whiteSpace=wrap;html=1;sketch=1;curveFitting=1;jiggle=2;fontFamily=Helvetica;fontStyle=1" parent="1" vertex="1">
<mxGeometry x="120" y="290" width="120" height="60" as="geometry"/>
</mxCell>
<mxCell id="7" value="&lt;h2&gt;display_menu&lt;/h2&gt;" style="whiteSpace=wrap;html=1;rounded=0;sketch=1;curveFitting=1;jiggle=2;fontFamily=Helvetica;fontStyle=1" parent="1" vertex="1">
<mxGeometry x="120" y="150" width="120" height="60" as="geometry"/>
</mxCell>
<mxCell id="10" value="&lt;h2&gt;init&amp;nbsp;&lt;/h2&gt;" style="whiteSpace=wrap;html=1;rounded=0;sketch=1;curveFitting=1;jiggle=2;fontFamily=Helvetica;fontStyle=1" parent="1" vertex="1">
<mxGeometry x="120" y="10" width="120" height="60" as="geometry"/>
</mxCell>
<mxCell id="13" value="&lt;h2&gt;confirm&lt;/h2&gt;" style="whiteSpace=wrap;html=1;rounded=0;sketch=1;curveFitting=1;jiggle=2;fontFamily=Helvetica;fontStyle=1" parent="1" vertex="1">
<mxGeometry x="120" y="430" width="120" height="60" as="geometry"/>
</mxCell>
<mxCell id="15" value="&lt;h2&gt;quit&amp;nbsp;&lt;/h2&gt;" style="whiteSpace=wrap;html=1;rounded=0;sketch=1;curveFitting=1;jiggle=2;fontFamily=Helvetica;fontStyle=1" parent="1" vertex="1">
<mxGeometry x="120" y="570" width="120" height="60" as="geometry"/>
</mxCell>
<mxCell id="78" style="edgeStyle=none;html=1;strokeColor=#B09500;fontColor=#f9f9f5;entryX=0.5;entryY=1;entryDx=0;entryDy=0;fillColor=#e3c800;sketch=1;curveFitting=1;jiggle=2;strokeWidth=2;fontFamily=Helvetica;fontStyle=1" parent="1" source="49" target="75" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="950" y="-190" as="targetPoint"/>
<Array as="points">
<mxPoint x="960" y="320"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="49" value="&lt;h2 style=&quot;background-color: rgb(30, 30, 30); font-size: 14px; line-height: 19px;&quot;&gt;&lt;font color=&quot;#f4f4f0&quot;&gt;DoRepaidBook&lt;/font&gt;&lt;/h2&gt;" style="whiteSpace=wrap;html=1;rounded=0;sketch=1;curveFitting=1;jiggle=2;fontFamily=Helvetica;fontStyle=1" parent="1" vertex="1">
<mxGeometry x="580" y="290" width="120" height="60" as="geometry"/>
</mxCell>
<mxCell id="88" style="edgeStyle=none;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;strokeColor=#001DBC;fontColor=#f9f9f5;fillColor=#0050ef;sketch=1;curveFitting=1;jiggle=2;strokeWidth=3;fontFamily=Helvetica;fontStyle=1" parent="1" source="50" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="1000" y="-30" as="targetPoint"/>
<Array as="points">
<mxPoint x="850" y="190"/>
<mxPoint x="850" y="-30"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="50" value="&lt;h2 style=&quot;background-color: rgb(30, 30, 30); font-size: 14px; line-height: 19px;&quot;&gt;&lt;font color=&quot;#f5f5f0&quot;&gt;DoPrintBook&lt;/font&gt;&lt;/h2&gt;" style="whiteSpace=wrap;html=1;rounded=0;sketch=1;curveFitting=1;jiggle=2;fontFamily=Helvetica;fontStyle=1" parent="1" vertex="1">
<mxGeometry x="580" y="160" width="120" height="60" as="geometry"/>
</mxCell>
<mxCell id="76" style="edgeStyle=none;html=1;strokeColor=#B09500;fontColor=#f9f9f5;entryX=0.5;entryY=1;entryDx=0;entryDy=0;fillColor=#e3c800;sketch=1;curveFitting=1;jiggle=2;strokeWidth=2;fontFamily=Helvetica;fontStyle=1" parent="1" source="52" target="75" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="950" y="-190" as="targetPoint"/>
<Array as="points">
<mxPoint x="960" y="50"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="87" style="edgeStyle=none;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;strokeColor=#001DBC;fontColor=#f9f9f5;fillColor=#0050ef;sketch=1;curveFitting=1;jiggle=2;strokeWidth=3;fontFamily=Helvetica;fontStyle=1" parent="1" source="52" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="1000" y="-30" as="targetPoint"/>
<Array as="points">
<mxPoint x="850" y="50"/>
<mxPoint x="850" y="-30"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="52" value="&lt;h2 style=&quot;background-color: rgb(30, 30, 30); font-size: 14px; line-height: 19px;&quot;&gt;&lt;font color=&quot;#f7f7f2&quot;&gt;DoDeleteBook&lt;/font&gt;&lt;/h2&gt;" style="whiteSpace=wrap;html=1;rounded=0;sketch=1;curveFitting=1;jiggle=2;fontFamily=Helvetica;fontStyle=1" parent="1" vertex="1">
<mxGeometry x="580" y="20" width="120" height="60" as="geometry"/>
</mxCell>
<mxCell id="77" style="edgeStyle=none;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;strokeColor=#B09500;fontColor=#f9f9f5;entryX=0.5;entryY=1;entryDx=0;entryDy=0;fillColor=#e3c800;sketch=1;curveFitting=1;jiggle=2;strokeWidth=2;fontFamily=Helvetica;fontStyle=1" parent="1" source="54" target="75" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="970" y="50" as="targetPoint"/>
<Array as="points">
<mxPoint x="960" y="-90"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="86" style="edgeStyle=none;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;strokeColor=#001DBC;fontColor=#f9f9f5;fillColor=#0050ef;sketch=1;curveFitting=1;jiggle=2;strokeWidth=3;fontFamily=Helvetica;fontStyle=1" parent="1" source="54" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="1000" y="-30" as="targetPoint"/>
<Array as="points">
<mxPoint x="850" y="-90"/>
<mxPoint x="850" y="-30"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="95" style="edgeStyle=none;sketch=1;hachureGap=4;jiggle=2;curveFitting=1;jumpSize=6;html=1;strokeColor=#4D9900;strokeWidth=3;fontFamily=Helvetica;fontSize=30;fontColor=#FFFFFF;startSize=6;" parent="1" source="54" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="850" y="750" as="targetPoint"/>
<Array as="points">
<mxPoint x="770" y="-90"/>
<mxPoint x="770" y="750"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="54" value="&lt;h2 style=&quot;background-color: rgb(30, 30, 30); font-size: 14px; line-height: 19px;&quot;&gt;&lt;font color=&quot;#d4d4d4&quot;&gt;&amp;nbsp;DoFindBook&lt;/font&gt;&lt;/h2&gt;" style="whiteSpace=wrap;html=1;rounded=0;sketch=1;curveFitting=1;jiggle=2;fontFamily=Helvetica;fontStyle=1" parent="1" vertex="1">
<mxGeometry x="580" y="-120" width="120" height="60" as="geometry"/>
</mxCell>
<mxCell id="83" style="edgeStyle=none;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;strokeColor=#BD7000;fontColor=#f9f9f5;fillColor=#f0a30a;strokeWidth=2;sketch=1;curveFitting=1;jiggle=2;fontFamily=Helvetica;fontStyle=1" parent="1" source="56" target="82" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="810" y="-230"/>
<mxPoint x="810" y="-340"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="85" style="edgeStyle=none;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;strokeColor=#001DBC;fontColor=#f9f9f5;fillColor=#0050ef;strokeWidth=2;sketch=1;curveFitting=1;jiggle=2;fontFamily=Helvetica;fontStyle=1" parent="1" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="700" y="-230" as="sourcePoint"/>
<mxPoint x="1000" y="-30" as="targetPoint"/>
<Array as="points">
<mxPoint x="850" y="-230"/>
<mxPoint x="850" y="-30"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="56" value="&lt;h2 style=&quot;background-color: rgb(30, 30, 30); font-size: 14px; line-height: 19px;&quot;&gt;&lt;font color=&quot;#f9f9f5&quot;&gt;DoAddBook&lt;/font&gt;&lt;/h2&gt;" style="whiteSpace=wrap;html=1;rounded=0;sketch=1;curveFitting=1;jiggle=2;fontFamily=Helvetica;fontStyle=1" parent="1" vertex="1">
<mxGeometry x="580" y="-260" width="120" height="60" as="geometry"/>
</mxCell>
<mxCell id="79" style="edgeStyle=none;html=1;strokeColor=#B09500;fontColor=#f9f9f5;entryX=0.5;entryY=1;entryDx=0;entryDy=0;fillColor=#e3c800;sketch=1;curveFitting=1;jiggle=2;strokeWidth=2;startSize=6;jumpSize=6;fontFamily=Helvetica;fontStyle=1" parent="1" source="58" target="75" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="970" y="50" as="targetPoint"/>
<Array as="points">
<mxPoint x="960" y="470"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="92" style="edgeStyle=none;sketch=1;hachureGap=4;jiggle=2;curveFitting=1;jumpSize=6;html=1;strokeColor=#4D9900;strokeWidth=3;fontFamily=Helvetica;fontSize=30;fontColor=#FFFFFF;startSize=6;" parent="1" source="58" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="850" y="750" as="targetPoint"/>
<Array as="points">
<mxPoint x="770" y="470"/>
<mxPoint x="770" y="750"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="58" value="&lt;h2 style=&quot;background-color: rgb(30, 30, 30); font-size: 14px; line-height: 19px;&quot;&gt;DoBoorowBook&lt;/h2&gt;" style="whiteSpace=wrap;html=1;rounded=0;sketch=1;curveFitting=1;jiggle=2;fontFamily=Helvetica;fontStyle=1" parent="1" vertex="1">
<mxGeometry x="580" y="440" width="120" height="60" as="geometry"/>
</mxCell>
<mxCell id="80" style="edgeStyle=none;html=1;strokeColor=#B09500;fontColor=#f9f9f5;entryX=0.5;entryY=1;entryDx=0;entryDy=0;fillColor=#e3c800;sketch=1;curveFitting=1;jiggle=2;strokeWidth=2;fontFamily=Helvetica;fontStyle=1" parent="1" source="60" target="75" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="970" y="50" as="targetPoint"/>
<Array as="points">
<mxPoint x="960" y="610"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="60" value="&lt;h2 style=&quot;background-color: rgb(30, 30, 30); font-size: 14px; line-height: 19px;&quot;&gt;&lt;font color=&quot;#f5f5f0&quot;&gt;DoReviseBook&lt;/font&gt;&lt;/h2&gt;" style="whiteSpace=wrap;html=1;rounded=0;sketch=1;curveFitting=1;jiggle=2;fontFamily=Helvetica;fontStyle=1" parent="1" vertex="1">
<mxGeometry x="580" y="580" width="120" height="60" as="geometry"/>
</mxCell>
<mxCell id="90" style="edgeStyle=none;sketch=1;hachureGap=4;jiggle=2;curveFitting=1;jumpSize=6;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;strokeColor=#4D9900;strokeWidth=3;fontFamily=Helvetica;fontSize=30;fontColor=#FFFFFF;startSize=6;" parent="1" source="62" target="89" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="62" value="&lt;h2 style=&quot;background-color: rgb(30, 30, 30); font-size: 14px; line-height: 19px;&quot;&gt;DoSortBook()&lt;/h2&gt;" style="whiteSpace=wrap;html=1;rounded=0;sketch=1;curveFitting=1;jiggle=2;fontFamily=Helvetica;fontStyle=1" parent="1" vertex="1">
<mxGeometry x="580" y="720" width="120" height="60" as="geometry"/>
</mxCell>
<mxCell id="75" value="&lt;h2&gt;&lt;span&gt;find&lt;/span&gt;&lt;/h2&gt;" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=#F0F0F0;fontColor=#f9f9f5;sketch=1;curveFitting=1;jiggle=2;fontFamily=Helvetica;fontStyle=1" parent="1" vertex="1">
<mxGeometry x="898" y="-250" width="120" height="60" as="geometry"/>
</mxCell>
<mxCell id="82" value="&lt;h2&gt;input&lt;/h2&gt;" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=#F0F0F0;fontColor=#f9f9f5;sketch=1;curveFitting=1;jiggle=2;fontFamily=Helvetica;fontStyle=1" parent="1" vertex="1">
<mxGeometry x="898" y="-370" width="120" height="60" as="geometry"/>
</mxCell>
<mxCell id="84" value="&lt;h2&gt;print&lt;/h2&gt;" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;sketch=1;curveFitting=1;jiggle=2;fontFamily=Helvetica;" parent="1" vertex="1">
<mxGeometry x="1000" y="-60" width="120" height="60" as="geometry"/>
</mxCell>
<mxCell id="89" value="&lt;div style=&quot;background-color: rgb(30, 30, 30); font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; line-height: 19px;&quot;&gt;&lt;h3 style=&quot;line-height: 19px;&quot;&gt;&lt;font color=&quot;#ffffff&quot;&gt;bookempty&lt;/font&gt;&lt;/h3&gt;&lt;/div&gt;" style="shape=process;whiteSpace=wrap;html=1;backgroundOutline=1;sketch=1;hachureGap=4;jiggle=2;curveFitting=1;fontFamily=Helvetica;fontSize=30;" parent="1" vertex="1">
<mxGeometry x="850" y="720" width="120" height="60" as="geometry"/>
</mxCell>
<mxCell id="98" value="&amp;nbsp;&lt;br&gt;" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontSize=30;fontFamily=Helvetica;fontColor=#FFFFFF;sketch=1;hachureGap=4;jiggle=2;curveFitting=1;fontSource=https%3A%2F%2Ffonts.googleapis.com%2Fcss%3Ffamily%3DArchitects%2BDaughter;" parent="1" vertex="1">
<mxGeometry x="-225" y="-65" width="30" height="50" as="geometry"/>
</mxCell>
<mxCell id="99" value="&amp;nbsp;&lt;br&gt;" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontSize=30;fontFamily=Helvetica;fontColor=#FFFFFF;sketch=1;hachureGap=4;jiggle=2;curveFitting=1;fontSource=https%3A%2F%2Ffonts.googleapis.com%2Fcss%3Ffamily%3DArchitects%2BDaughter;" parent="1" vertex="1">
<mxGeometry x="585" y="1265" width="30" height="50" as="geometry"/>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

@ -1,5 +1,5 @@
# 图书管理系统 # 图书管理系统
2023年4月22 2023年5月1
杨腾泽,孙英皓,李聪颖,刘彩月 杨腾泽,孙英皓,李聪颖,刘彩月
## 项目简介 ## 项目简介
@ -9,8 +9,8 @@
项目开发过程中采用 Kanban看板进行任务管理和分工协作并使用 Git 对程序代码和文档进行版本管理。任务分工情况如下: 项目开发过程中采用 Kanban看板进行任务管理和分工协作并使用 Git 对程序代码和文档进行版本管理。任务分工情况如下:
|任务 |设计 |开发 |测试 |文档 | |任务 |设计 |开发 |测试 |文档 |
|------ |-------|-------|--------|-------| |------ |-------|-------|--------|-------|
|Ca-Cb | | | | 杨腾泽 | |Ca-Cb | | | | 孙英皓 |
|C0-C2 | | | | 孙英皓 | |C0-C2 | | | | 杨腾泽 |
|C3-C5 | | | | 刘彩月 | |C3-C5 | | | | 刘彩月 |
|C6-C8 | | | | 李聪颖 | |C6-C8 | | | | 李聪颖 |
@ -22,6 +22,7 @@
## 关于图书管理系统 ## 关于图书管理系统
设计一个图书管理系统,要求采用命令行菜单界面进行交互,具备查书、借书、还书、打印书籍 、添加、删除等基本功能,能够以表格和图表形式展示数据,采用 CSV 格式保存数据。 设计一个图书管理系统,要求采用命令行菜单界面进行交互,具备查书、借书、还书、打印书籍 、添加、删除等基本功能,能够以表格和图表形式展示数据,采用 CSV 格式保存数据。
\
系统的功能性需求: 系统的功能性需求:
- 数据的查书、借书、还书、打印书籍、添加、删除展示。 - 数据的查书、借书、还书、打印书籍、添加、删除展示。
@ -60,9 +61,70 @@
确定要退出吗?(Y/N): n 确定要退出吗?(Y/N): n
程序退出 程序退出
``` ```
### C1: 查找图书
选择菜单命令: 1 提示Find Book 和 Enter book ID: 字样若本身书籍库为空则提示Book data empty。继续输入图书编号。若没找到提示Not found;若找到提示Found 并 打印书籍信息。
```
请选择1
Find Book
Book data empty
```
```
请选择1
Find Book
Enter book ID: 1
Not found
```
```
请选择1
Find Book
Enter book ID: 1
Found
************
Book
**************** id: 1 ****************
**** title: 《 2 》****
************** Number: 3 **************
```
### C2:借用图书
选择菜单命令2提示 Boorow Book若本身书籍库为空则提示Book data empty。提示 Which book you wanna boorow ?则继续输入图书编号。若该书本身不存在则提示NOT FOUND THIS BOOK如图书存在则提示OK。
```
请选择2
Boorow Book
Book data empty
```
```
请选择2
Boorow Book
Which book you wanna boorow ?
2
NOT FOUND THIS BOOK
```
```
请选择2
Boorow Book
Which book you wanna boorow ?
1
*********
OK
*********
```
### C3:归还图书 ### C3:归还图书
选择菜单命令3 提示归还图书 和 你想要归还哪一本书?输入图书编号,若在系统中没有该图书,则添加图书并输入图书的编号,数量和数目,显示相关信息并归还成功,否则直接退出。 选择菜单命令3提示归还图书 和 你想要归还哪一本书?输入图书编号,若在系统中没有该图书,则添加图书并输入图书的编号,数量和数目,显示相关信息并归还成功,否则直接退出。
````` `````
请选择3 请选择3
@ -95,7 +157,7 @@ Which book you wanna repaid ?
````` `````
### C4打印书籍 ### C4打印书籍
选择菜单命令4 提示打印书籍并打印图书信息若没有书则输出Total: 0 books若有书则输出书籍信息 选择菜单命令4提示打印书籍并打印图书信息若没有书则输出Total: 0 books若有书则输出书籍信息
``` ```
请选择4 请选择4
@ -188,6 +250,7 @@ Which book you wanna revise ?
2 2
No such book No such book
`````` ``````
# 概要设计 # 概要设计
系统主要分为用户界面和数据处理两大模块。 系统主要分为用户界面和数据处理两大模块。

@ -1,231 +1,235 @@
#ifndef DATA_H_INCLUDED #ifndef DATA_H_INCLUDED
#define DATA_H_INCLUDED #define DATA_H_INCLUDED
#include <stdio.h> #include <stdio.h>
#include "sqlist.h" #include "sqlist.h"
struct Book { struct Book {
int id; // 编号 int id; // 编号
string title; // 标题 string title; // 标题
int number; // 数量 int number; // 数量
}; };
SqList <Book> books; SqList <Book> books;
// 函数声明 // 函数声明
bool bookempty(); // 书籍库判空 bool bookempty(); // 书籍库判空
void input(Book& b); // 输入一本书的信息 void input(Book& b); // 输入一本书的信息
void print(const Book& b);// 打印一本书的信息 void print(const Book& b);// 打印一本书的信息
int find(int id); // 根据 id 查找图书 || 若找到,返回元素的位序,找不到时返回 0 int find(int id); // 根据 id 查找图书 || 若找到,返回元素的位序,找不到时返回 0
void DoAddBook(); // 添加图书 void DoAddBook(); // 添加图书
void DoFindBook(); // 查找图书 void DoFindBook(); // 查找图书
void DoDeleteBook(); // 删除图书 void DoDeleteBook(); // 删除图书
void DoPrintBook(); // 打印所有图书 void DoPrintBook(); // 打印所有图书
void DoRepaidBook(); // 归还图书 void DoRepaidBook(); // 归还图书
void DoBoorowBook(); // 借用图书 void DoBoorowBook(); // 借用图书
void DoReviseBook(); // 修改图书 void DoReviseBook(); // 修改图书
void DoSortBook(); // 排序图书 void DoSortBook(); // 排序图书
// 输入一本书的信息 // 输入一本书的信息
void input(Book& b) void input(Book& b)
{ {
cout << "ID : "; cout << "ID : ";
cin >> b.id; cin >> b.id;
cin.ignore(1024, '\n'); // skip rest chars of the line cin.ignore(1024, '\n'); // skip rest chars of the line
cout << "TITLE : "; cout << "TITLE : ";
getline(cin, b.title); getline(cin, b.title);
cout << "Number : "; cout << "Number : ";
while (1){ while (1){
cin >> b.number; cin >> b.number;
if (b.number>0) break; if (b.number>0) break;
cout << "Number ERROR" << endl; cout << "Number ERROR" << endl;
cout << "Input again" << endl; cout << "Input again" << endl;
} }
} }
// 打印一本书的信息 // 打印一本书的信息
void print(const Book& b) void print(const Book& b)
{ {
cout << "Book " << endl << endl cout << "Book " << endl << endl
<<"**************** id: " << b.id << " ****************" << endl <<"**************** id: " << b.id << " ****************" << endl
<< "**** title: 《 " << b.title << " 》****" << endl << "**** title: 《 " << b.title << " 》****" << endl
<< "************** Number: " << b.number << " **************" << endl << endl; << "************** Number: " << b.number << " **************" << endl << endl;
} }
// 根据 id 查找图书 // 根据 id 查找图书
// 若找到,返回元素的位序,找不到时返回 0 // 若找到,返回元素的位序,找不到时返回 0
int find(int id) int find(int id)
{ {
for (int i = 1; i <= books.length; i++) for (int i = 1; i <= books.length; i++)
{ {
if (id == books.elem[i].id){ if (id == books.elem[i].id){
return i; return i;
} }
} }
return 0; // not found return 0; // not found
} }
// 书籍库判空 // 书籍库判空
bool bookempty() bool bookempty()
{ {
int a=0; int a=0;
for (int i=1;i<=books.length;i++) for (int i=1;i<=books.length;i++)
{ {
if (find(i)==0) a++; if (find(i)==0) a++;
} }
if (a==books.length) return true; if (a==books.length) return true;
else return false; else return false;
} }
// 添加图书 // 添加图书
void DoAddBook() void DoAddBook()
{ {
cout << endl << "Add Book"<< endl<<endl; cout << endl << "Add Book"<< endl<<endl;
Book book; Book book;
input(book); //输入图书 input(book); //输入图书
books.elem[books.length + 1] = book; books.elem[books.length + 1] = book;
books.length++; books.length++;
print(book); print(book);
cout << "*******Added********" << endl; cout << "*******Added********" << endl;
} }
// 查找图书 // 查找图书
void DoFindBook() void DoFindBook()
{ {
cout << endl << "Find Book" << endl <<endl; cout << endl << "Find Book" << endl <<endl;
int id; if (bookempty()) cout << "Book data empty"<< endl;
cout << "Enter book ID: "; int id;
cin >> id; cout << "Enter book ID: ";
cin >> id;
Book book;
if (find(id) == 0) Book book;
cout << "Not found" << endl; if (find(id) == 0)
else cout << "Not found" << endl;
{ else
book = books.elem[find(id)]; {
cout << "Found" << endl; book = books.elem[find(id)];
cout << "************" << endl; cout << "Found" << endl;
print(book); cout << "************" << endl;
} print(book);
} }
}
// 删除图书
void DoDeleteBook() // 删除图书
{ void DoDeleteBook()
cout << endl << "Delete Book" << endl << endl; {
int id; cout << endl << "Delete Book" << endl << endl;
cout << "Which book you wanna delelet?"<<endl; int id;
cout << "Enter book ID: "; cout << "Which book you wanna delelet?"<<endl;
cin >> id; cout << "Enter book ID: ";
Book e; cin >> id;
if (find(id) == 0) Book e;
cout << "Not found" << endl; if (find(id) == 0)
else cout << "Not found" << endl;
{ else
e = books.elem[find(id)]; {
print(e); e = books.elem[find(id)];
for (int i = find(id); i < books.length; i++) print(e);
{ for (int i = find(id); i < books.length; i++)
books.elem[i] = books.elem[i + 1]; {
} books.elem[i] = books.elem[i + 1];
--books.length; }
cout << "************************" << endl; --books.length;
cout << "Deleted" << endl; cout << "************************" << endl;
} cout << "Deleted" << endl;
} }
}
// 打印所有图书
void DoPrintBook() // 打印所有图书
{ void DoPrintBook()
cout << endl << "Print All Books" << endl <<endl; {
int flag = 0; cout << endl << "Print All Books" << endl <<endl;
for (int i = 0; i < books.length; i++) int flag = 0;
{ for (int i = 0; i < books.length; i++)
Book e; {
e = books.elem[i + 1]; Book e;
print(e); e = books.elem[i + 1];
flag++; print(e);
} flag++;
cout << "Total: "; }
cout << flag; cout << "Total: ";
cout << " books" << endl; cout << flag;
} cout << " books" << endl;
}
// 归还图书
void DoRepaidBook() // 归还图书
{ void DoRepaidBook()
cout << endl << "Repaid Book" << endl<<endl; {
int id; cout << endl << "Repaid Book" << endl<<endl;
cout << "Which book you wanna repaid ? " << endl; int id;
cin >> id; cout << "Which book you wanna repaid ? " << endl;
cout << endl; cout << "Enter book ID :" << endl;
if (find(id)){ cin >> id;
Book e; cout << endl;
e = books.elem[find(id)]; if (find(id)){
++books.elem[find(id)].number; Book e;
}else{ e = books.elem[find(id)];
DoAddBook(); ++books.elem[find(id)].number;
} }else{
} DoAddBook();
}
// 借用图书 }
void DoBoorowBook()
{ // 借用图书
cout << endl << "Boorow Book" << endl <<endl; void DoBoorowBook()
int id; {
cout << "Which book you wanna boorow ? " << endl; cout << endl << "Boorow Book" << endl <<endl;
cin >> id; int id;
cout << endl; if (bookempty()) cout << "Book data empty"<< endl;
if (find(id)){ cout << "Which book you wanna boorow ? " << endl;
if (books.elem[find(id)].number>0) { cout << "Enter book ID :" << endl;
Book e; cin >> id;
e = books.elem[find(id)]; cout << endl;
cout<< "*********"<< endl << "OK" << endl << "*********"<<endl; if (find(id)){
--books.elem[find(id)].number; if (books.elem[find(id)].number>0) {
}else cout << "***************************"<< endl Book e;
<< "Book empty" << endl << "***************************" << endl; e = books.elem[find(id)];
}else cout<< "NOT FOUND THIS BOOK"<<endl; cout<< "*********"<< endl << "OK" << endl << "*********"<<endl;
} --books.elem[find(id)].number;
}else cout << "***************************"<< endl
// 修改图书 << "Book empty" << endl << "***************************" << endl;
void DoReviseBook() }else cout<< "NOT FOUND THIS BOOK"<<endl;
{ }
cout <<endl<< "Revise Book" <<endl <<endl;
int id; // 修改图书
printf( "Which book you wanna revise ?\n" ); void DoReviseBook()
cin >> id; {
cout <<endl<< "Revise Book" <<endl <<endl;
if ( find(id)!=0 ) { int id;
printf ( "Original book number : %d\n", books.elem[id].number ); printf( "Which book you wanna revise ?\n" );
printf ( "Revised number :" ); cin >> id;
int xiugai;
scanf ( "%d", &xiugai ); if ( find(id)!=0 ) {
books.elem[id].number+=xiugai; printf ( "Original book number : %d\n", books.elem[id].number );
cout << "**********************" << endl; printf ( "Revised number :" );
printf ( "Revise success \n" ); int xiugai;
} scanf ( "%d", &xiugai );
else printf ( "No such book\n"); books.elem[id].number+=xiugai;
} cout << "**********************" << endl;
printf ( "Revise success \n" );
// 排序图书 }
void DoSortBook() else printf ( "No such book\n");
{ }
cout << endl << "Sort Books" << endl << endl;
int a=0; // 排序图书
if (bookempty()) cout << "Book data empty"<< endl; void DoSortBook()
else { {
for (int i=1;i<books.length;i++) cout << endl << "Sort Books" << endl << endl;
for (int j=books.length;j>0;j--) int a=0;
{ if (bookempty()) cout << "Book data empty"<< endl;
if (books.elem[i].id>books.elem[j].id) { else {
Book temp=books.elem[i];books.elem[i]=books.elem[j];books.elem[j]=temp;} for (int i=1;i<books.length;i++)
} for (int j=books.length;j>0;j--)
} {
cout << "*****************************" <<endl; if (books.elem[i].id>books.elem[j].id) {
cout << "Sort success"<<endl; Book temp=books.elem[i];books.elem[i]=books.elem[j];books.elem[j]=temp;}
} }
}
cout << "*****************************" <<endl;
cout << "Sort success"<<endl;
}
#endif // DATA_H_INCLUDED #endif // DATA_H_INCLUDED

@ -1,177 +1,177 @@
/////////////////////////////////////// ///////////////////////////////////////
/// file: sqlist.h /// file: sqlist.h
/// Sequential list /// Sequential list
/////////////////////////////////////// ///////////////////////////////////////
#pragma once #pragma once
#include <stdexcept> // for std::out_of_range #include <stdexcept> // for std::out_of_range
using std::out_of_range; // 导入名称 using std::out_of_range; // 导入名称
using std::length_error; using std::length_error;
/////////////////////////////////////// ///////////////////////////////////////
/// 存储结构 /// 存储结构
/// ///
/// 线性表的顺序存储结构 /// 线性表的顺序存储结构
/// ///
template <typename E, int MAXSIZE = 256> template <typename E, int MAXSIZE = 256>
struct SqList struct SqList
{ {
E elem[MAXSIZE]; E elem[MAXSIZE];
int length; int length;
}; };
/////////////////////////////////////// ///////////////////////////////////////
/// 基本操作 /// 基本操作
/// ///
/// 构造空的顺序表 L /// 构造空的顺序表 L
/// ///
template <typename E, int M> template <typename E, int M>
void InitList(SqList<E, M> &L) void InitList(SqList<E, M> &L)
{ {
L.length = 0; // 空表长度为 0 L.length = 0; // 空表长度为 0
} }
/// ///
/// 销毁顺序表 L /// 销毁顺序表 L
/// ///
template <typename E, int M> template <typename E, int M>
void DestroyList(SqList<E, M> &L) void DestroyList(SqList<E, M> &L)
{ {
// do nothing // do nothing
} }
/// ///
/// 将顺序表 L 置为空表 /// 将顺序表 L 置为空表
/// ///
template <typename E, int M> template <typename E, int M>
void ClearList(SqList<E, M> &L) void ClearList(SqList<E, M> &L)
{ {
L.length = 0; L.length = 0;
} }
/// ///
/// 若 L 为空表,则返回 true否则返回 false /// 若 L 为空表,则返回 true否则返回 false
/// ///
template <typename E, int M> template <typename E, int M>
bool ListEmpty(const SqList<E, M> &L) bool ListEmpty(const SqList<E, M> &L)
{ {
return L.length == 0; return L.length == 0;
} }
/// ///
/// 返回顺序表 L 中数据元素个数 /// 返回顺序表 L 中数据元素个数
/// ///
template <typename E, int M> template <typename E, int M>
int ListLength(const SqList<E, M> &L) int ListLength(const SqList<E, M> &L)
{ {
return L.length; return L.length;
} }
/// ///
/// 用 e 返回顺序表 L 中第 i 个数据元素1<=i<=length /// 用 e 返回顺序表 L 中第 i 个数据元素1<=i<=length
/// ///
template <typename E, int M> template <typename E, int M>
bool GetElem(const SqList<E, M> &L, int i, E &e) bool GetElem(const SqList<E, M> &L, int i, E &e)
{ {
// 若 i 值不合法,则返回 false // 若 i 值不合法,则返回 false
if (i < 1 || i > L.length) if (i < 1 || i > L.length)
return false; return false;
// 取第 i 个元素 // 取第 i 个元素
e = L.elem[i - 1]; e = L.elem[i - 1];
// 返回 true 表示操作成功 // 返回 true 表示操作成功
return true; return true;
} }
/// ///
/// 取顺序表 L 中第 i 个元素 /// 取顺序表 L 中第 i 个元素
/// ///
template <typename E, int M> template <typename E, int M>
const E &GetElem(const SqList<E, M> &L, int i) const E &GetElem(const SqList<E, M> &L, int i)
{ {
// 若 i 值不合法,不能取元素 // 若 i 值不合法,不能取元素
if (i < 1 || i > L.length) if (i < 1 || i > L.length)
throw out_of_range("i out of range"); throw out_of_range("i out of range");
// 返回第 i 个元素 // 返回第 i 个元素
return L.elem[i - 1]; return L.elem[i - 1];
} }
/// ///
/// 在顺序表 L 中第 i 个位置之前插入新的数据元素 e /// 在顺序表 L 中第 i 个位置之前插入新的数据元素 e
/// ///
template <typename E, int MAXSIZE> template <typename E, int MAXSIZE>
void ListInsert(SqList<E, MAXSIZE> &L, int i, E e) void ListInsert(SqList<E, MAXSIZE> &L, int i, E e)
{ {
// 若表满,则不能插入 // 若表满,则不能插入
if (L.length == MAXSIZE) if (L.length == MAXSIZE)
throw length_error("L is full"); throw length_error("L is full");
// 若 i 值不合法,则不能插入 // 若 i 值不合法,则不能插入
if (i < 1 || i > L.length + 1) if (i < 1 || i > L.length + 1)
throw out_of_range("i out of range"); throw out_of_range("i out of range");
// 插入位置及之后的元素后移 // 插入位置及之后的元素后移
for (int j = L.length - 1; j >= i - 1; j--) for (int j = L.length - 1; j >= i - 1; j--)
{ {
L.elem[j + 1] = L.elem[j]; L.elem[j + 1] = L.elem[j];
} }
// 插入元素 // 插入元素
L.elem[i - 1] = e; L.elem[i - 1] = e;
// 表长增 1 // 表长增 1
L.length++; L.length++;
} }
/// ///
/// 在顺序表 L 中删除第 i 个元素,用 e 返回 /// 在顺序表 L 中删除第 i 个元素,用 e 返回
/// ///
template <typename E, int M> template <typename E, int M>
void ListDelete(SqList<E, M> &L, int i, E &e) void ListDelete(SqList<E, M> &L, int i, E &e)
{ {
// 若 i 值不合法,则不能删除 // 若 i 值不合法,则不能删除
if (i < 1 || i > L.length) if (i < 1 || i > L.length)
throw out_of_range("i out of range"); throw out_of_range("i out of range");
// 取出被删除元素 // 取出被删除元素
e = L.elem[i - 1]; e = L.elem[i - 1];
// 被删除元素之后的元素前移 // 被删除元素之后的元素前移
for (int j = i; j < L.length; j++) for (int j = i; j < L.length; j++)
{ {
L.elem[j - 1] = L.elem[j]; L.elem[j - 1] = L.elem[j];
} }
// 表长减 1 // 表长减 1
L.length--; L.length--;
} }
/// ///
/// 返回顺序表 L 中第一个与 e 满足关系 compare 的数据元素的位序 /// 返回顺序表 L 中第一个与 e 满足关系 compare 的数据元素的位序
/// 若这样的数据元素不存在,则返回 0。 /// 若这样的数据元素不存在,则返回 0。
/// ///
template <typename E, int M, typename Cmp> template <typename E, int M, typename Cmp>
int LocateElem(const SqList<E, M> &L, const E &e, Cmp compare) int LocateElem(const SqList<E, M> &L, const E &e, Cmp compare)
{ {
// 逐个取出元素与 e 比较 // 逐个取出元素与 e 比较
for (int i = 0; i < L.length; i++) for (int i = 0; i < L.length; i++)
{ {
// 若满足条件,则返回位序 // 若满足条件,则返回位序
if (compare(L.elem[i], e)) if (compare(L.elem[i], e))
return i + 1; return i + 1;
} }
return 0; // 不存在 return 0; // 不存在
} }
/// ///
/// 遍历顺序表,依次对 L 中的每个数据元素调用函数 visit /// 遍历顺序表,依次对 L 中的每个数据元素调用函数 visit
/// ///
template <typename E, int M, typename Func> template <typename E, int M, typename Func>
void ListTraverse(const SqList<E, M> &L, Func visit) void ListTraverse(const SqList<E, M> &L, Func visit)
{ {
for (int i = 0; i < L.length; i++) for (int i = 0; i < L.length; i++)
{ {
visit(L.elem[i]); visit(L.elem[i]);
} }
} }

@ -1,126 +1,126 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <iostream> #include <iostream>
using namespace std; using namespace std;
#include "data.h" #include "data.h"
#include "sqlist.h" #include "sqlist.h"
enum { enum {
CMD_QUIT, // 退出程序 CMD_QUIT, // 退出程序
CMD_QUERY, // 查书(数量) CMD_QUERY, // 查书(数量)
CMD_BOOROW, // 借用书籍 CMD_BOOROW, // 借用书籍
CMD_REPAID, // 归还书籍 CMD_REPAID, // 归还书籍
CMD_PRINT, // 打印书籍 CMD_PRINT, // 打印书籍
CMD_INSERT, // 添加书籍 CMD_INSERT, // 添加书籍
CMD_DELETE, // 删除书籍 CMD_DELETE, // 删除书籍
CMD_UPDATE, // 修改书籍 CMD_UPDATE, // 修改书籍
CMD_SORT, // 排序书籍 CMD_SORT, // 排序书籍
}; };
// 函数声明 // 函数声明
void init(void); // 程序启动 void init(void); // 程序启动
void quit(void); // 程序退出 void quit(void); // 程序退出
void display_menu(void); // 显示命令菜单 void display_menu(void); // 显示命令菜单
int make_choice(void); // 选择命令 int make_choice(void); // 选择命令
int confirm(const char* msg); // 确认 int confirm(const char* msg); // 确认
// 主函数 // 主函数
int main(void) int main(void)
{ {
init(); // 程序启动 init(); // 程序启动
InitList(books); InitList(books);
for(;;) { for(;;) {
display_menu(); // display_menu(); //
int c = make_choice(); int c = make_choice();
switch(c) { switch(c) {
case CMD_REPAID:// 还书 case CMD_REPAID:// 还书
{DoRepaidBook(); {DoRepaidBook();
break;} break;}
case CMD_BOOROW:// 借书 case CMD_BOOROW:// 借书
{DoBoorowBook(); {DoBoorowBook();
break;} break;}
case CMD_PRINT:// 打印所有书籍 case CMD_PRINT:// 打印所有书籍
{DoPrintBook(); {DoPrintBook();
break;} break;}
case CMD_QUERY:// 查找书籍 case CMD_QUERY:// 查找书籍
{DoFindBook(); {DoFindBook();
break;} break;}
case CMD_INSERT:// 添加书籍 case CMD_INSERT:// 添加书籍
{DoAddBook(); {DoAddBook();
break;} break;}
case CMD_DELETE:// 删除书籍 case CMD_DELETE:// 删除书籍
{DoDeleteBook(); {DoDeleteBook();
break;} break;}
case CMD_UPDATE:// 修改书籍 case CMD_UPDATE:// 修改书籍
{DoReviseBook(); {DoReviseBook();
break;} break;}
case CMD_SORT: // 排序书籍 case CMD_SORT: // 排序书籍
{DoSortBook(); {DoSortBook();
break;} break;}
case CMD_QUIT:// 退出程序 case CMD_QUIT:// 退出程序
{if (confirm("确定要退出吗?")) quit(); // 仅在确认后退出 {if (confirm("确定要退出吗?")) quit(); // 仅在确认后退出
break;} break;}
default: default:
puts("命令错误,请重新选择"); puts("命令错误,请重新选择");
break;} break;}
} }
quit(); // 程序退出 quit(); // 程序退出
DestroyList(books); DestroyList(books);
return 0; return 0;
} }
void init(void) void init(void)
{ {
puts("*******图书管理系统启动*******"); puts("*******图书管理系统启动*******");
} }
void quit(void) void quit(void)
{ {
puts("系统退出"); puts("系统退出");
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} }
void display_menu(void) void display_menu(void)
{ {
cout << "————————————————————————————————————————————————————————————————"<<endl; cout << "————————————————————————————————————————————————————————————————"<<endl;
printf("| %d 查书 | %d 借书 | %d 还书 | %d 打印 | %d 添加 |\n| %d 删除 | %d 修改 | %d 排序 | %d 退出 |\n", printf("| %d 查书 | %d 借书 | %d 还书 | %d 打印 | %d 添加 |\n| %d 删除 | %d 修改 | %d 排序 | %d 退出 |\n",
CMD_QUERY,CMD_BOOROW,CMD_REPAID,CMD_PRINT,CMD_INSERT,CMD_DELETE,CMD_UPDATE,CMD_SORT,CMD_QUIT); CMD_QUERY,CMD_BOOROW,CMD_REPAID,CMD_PRINT,CMD_INSERT,CMD_DELETE,CMD_UPDATE,CMD_SORT,CMD_QUIT);
cout << "————————————————————————————————————————————————————————————————"<<endl; cout << "————————————————————————————————————————————————————————————————"<<endl;
} }
int make_choice(void) int make_choice(void)
{ {
int c; // 用户输入 int c; // 用户输入
int n = 0; // 正确读入的数据项个数 int n = 0; // 正确读入的数据项个数
while (n == 0) { while (n == 0) {
printf("请选择:"); printf("请选择:");
n = scanf("%d", &c); // 尝试读入整数 c n = scanf("%d", &c); // 尝试读入整数 c
scanf("%*[^\n]"); // 跳过一行中剩余的字符 scanf("%*[^\n]"); // 跳过一行中剩余的字符
} }
return c; return c;
} }
int confirm(const char* msg) int confirm(const char* msg)
{ {
char c = 'n'; // 默认选择是 no char c = 'n'; // 默认选择是 no
printf("%s(Y/N): ", msg); // 提示输入 yes/no 进行确认s printf("%s(Y/N): ", msg); // 提示输入 yes/no 进行确认s
scanf(" %c%*[^\n]", &c); // 读取第一个字符,忽略剩余字符 scanf(" %c%*[^\n]", &c); // 读取第一个字符,忽略剩余字符
return c == 'y' || c == 'Y'; // 返回确认结果 return c == 'y' || c == 'Y'; // 返回确认结果
} }

@ -0,0 +1,6 @@
*******图书管理系统启动*******
————————————————————————————————————————————————————————————————
| 1 查书 | 2 借书 | 3 还书 | 4 打印 | 5 添加 |
| 6 删除 | 7 修改 | 8 排序 | 0 退出 |
————————————————————————————————————————————————————————————————
请选择:
Loading…
Cancel
Save