第一次大作业(大一)Project 1. 设计仓库管理系统
题目
写在前面
这是我在CDSN的第一篇博客呢
为什么要写博客呢
其实是想在这里写学习笔记啦
因为手写容易写错而且很费劲
好吧 那我这个菜鸡 就要开始我的博客笔记生涯啦!!
(顺便要说一下~因为下面要写的有一部分是之前抄在笔记本上面的,所以没有记下来源呜呜,不过都是在社区里面看到的噢,按关键字都很容易搜到呢因为写的贼好,那作者如果觉得有侵犯版权的话请联系我呀)
我新学的知识
system(“cls”);
是指清屏
就是说 清除当前屏幕的所有东西,比如输出的数据或者你输入的一些东西,都会被清理掉
下面的代码是在VC环境中使用的
#include<windows.h>
system("cls");
至于这个清屏应该用什么头文件,我太菜没看懂搜出来的
不过我在devcpp中用c++的写的时候并没有加除了#include和#include的任何头文件就就直接可以用哒
关于#ifndef #define 和 #endif
这个可以防止头文件被重复引用噢
具体“被重复引用”就是指:比如一个a.h中包含了#include"b.h",然后有一个c.cpp导入了#include"a.h",这就造成了重复引用
主要引起的后果有:
1.造成效率低,耗费时间
2.有些情况下还会引起错误
#ifndef A_H //if not define a.h
#define A_H //define a.h
//你的代码
#endif
关于fstream
这个链接讲的很不错呢
但我还是要做一下笔记,其实大概也是抄一遍链接里面的东西啦嘻嘻
stream 是c++中的一个类,ofstream和ifstream都是它的子类
所有的I/O都是以这个“流”类作为基础的
头文件
#include<fstream>
打开文件
在fstream类中,有一个成员函数open,用来打开文件
函数原型 void open(const char* filename,int mode,int access);
其中参数:filename指要打开的文件名,mode指文件的打开方式,access指要打开文件的属性
而打开文件的具体方法在类ios(所有流式类的基类)中定义,如下
ios::app //以追加的方式打开文件
ios::ate //文件打开后定位到文件尾,ios:app就包含有此属性
ios::binary //以二进制方式打开文件,缺省的方式是文本方式
ios::in //文件以输入方式打开(文件数据输入到内存)
ios::out //文件以输出方式打开(内存数据输出到文件)
ios::nocreate //不建立文件,所以文件不存在时打开失败
ios::noreplace//不覆盖文件,所以打开文件时如果文件存在失败
ios::trunc //如果文件存在,把文件长度设为0
这里要记一下我不太懂的地方:
1.什么是以追加的方式打开文件?
根据我搜索得到的结果,是指打开该文件并且在文件末尾添加新的内容
2.以二进制方式打开文件和以文本方式打开文件的区别
我还是搜索了一下,得到了以下结果:
二进制方式和文本方式其实没有太大区别,甚至可以说,文本方式是某种特殊的二进制方式 在占用空间上面,二进制还是要小一些。
3.以输入和输出方式
输入,就是把文件导入到程序
输出,就是将数据写入文件中(我其实不确定对不对,要是有人知道是错的希望纠正,蟹蟹~
4.ios::nocreate和ios::noreplace
ios::nocreate:打开一个以有的文件,如文件不存在,则打开失败,nocreate的意思是不建立新文件
ios::noreplace:如果文件不存在则建立新文件,如果文件以存在则操作失败,noplace的意思是不建立新文件
5.ios::trunc
覆盖存在的文件 即如果原来文件中有数据原来的数据就被清空了,清空后再写入就可以了
打开文件的属性取值是:
数字 | 属性 |
---|---|
0 | 普通文件,打开访问 |
1 | 只读文件 |
2 | 隐含文件 |
4 | 系统文件 |
可以用“或”或者“+”把以上属性连接起来,如3或1|2就是以只读和隐含属性打开文件。
ofstream,ifstream和fstream这几个类的open函数的默认打开文件的方式不同
类 | 默认打开方式 |
---|---|
ofsteam | ios::out或ios:trunc |
ifstream | ios::in |
ftream | ios::in或ios::out |
只有当函数被调用时没有声明方式参数的情况下,默认值才会被采用。如果函数被调用时声明了任何参数,默认值将被完全改写,而不会与调用参数组合。
由于对类ofstream, ifstream 和 fstream 的对象所进行的第一个操作通常都是打开文件,这些类都有一个构造函数可以直接调用open 函数,并与open函数拥有同样的参数。也就是说,我们也可以这样来打开文件:
ofstream out("Hello.txt");
ifstream in("...");
fstream foi("...");
如果你不放心,可以
通过调用成员函数is_open()来检查一个文件是否已经被顺利的打开了:
bool is_open();
它返回一个布尔(bool)值,为真(true)代表文件已经被顺利打开,假( false )则相反。
关闭文件
关闭文件需要调用成员函数close(),它负责将缓存中的数据排放出来并关闭文件。它的格式很简单:
void close();
这个函数一旦被调用,原先的流对象(stream object)就可以被用来打开其它的文件了,这个文件也就可以重新被其它的进程(process)所有访问了。
为防止流对象被销毁时还联系着打开的文件,析构函数(destructor)将会自动调用关闭函数close。
那我要找一下,什么是析构函数呢?老师上课其实有讲但是我没有听懂
其实我还是没怎么懂,而且很长,可能要另写一篇来学习了
那我摘录一下重要的部分
1.析构函数和构造函数是一对。构造函数用于创建对象,而析构函数是用来撤销对象
2.析构函数是这样写的:如~NoName()
,它与构造函数唯一的区别就是,前面都加了一个 ~ 符号。 析构函数都是没有参数的,也就是说:析构函数永远只能写一个。
3.如果我们不写析构函数,C++ 会帮我们写一个析构函数。C++帮我们写的这个析构函数只能做一些很简单的工作,它不会帮助我们去打开文件、连接数据库、分配内存这些操作,相应的回收,它也不会给我们写。所以需要我们自己手动的写。(如果要做这些操作,我们必须自己写。)
4.只要你写了析构函数,就必须要写 赋值构造函数 和 赋值运算符,这就是著名的 三法则 (rule of three)
文本文件的读写
1.文件的写入
// writing on a text file
#include <fiostream.h>
int main () {
ofstream examplefile ("example.txt");
if (examplefile.is_open()) {
examplefile << "This is a line.\n";
examplefile << "This is another line.\n";
examplefile.close();
}
return 0;
}
我们得到的输出是:
This is a line.
This is another line.
个人觉得这个代码更清晰一点
//writing on a text file
#include <fiostream.h>
int main () {
ofstream out("out.txt");
if (out.is_open()){
out << "This is a line.\n";
out <<"This is another line.\n";
out.close();
}
return 0;
}
//结果: 在out.txt中写入:
This is a line.
This is another line .
2.文件的输出
//reading a text file
#include<iostream.h>
#include<fstream.h>
#include<stdlib.h>
int main(){
char buffer[256];
ifstream in("test.txt");
if(!in.is_open()){
cout << "Error opening file";
exit (1);
}
while(!in.eof()){
in.getline(buffer,100);
cout<<buffer<<endl;
}
return 0;
}
//最后输出
This is a line.
This is another line.
那现在要说一下getline(),和cin一个作用(就我理解)
还有eof()是指到达文件末尾是返回true
在这之后还有几个验证流状态的成员函数,如bad(), fail(), good(), 在这里就先不多说啦(希望暂时不会用到)
已经过去一周啦,这几天在忙其他作业。今天一定要写完啦!
先在这里贴两个我找到的仓库管理系统的网址~
仓库管理系统1
仓库管理系统2
接下来呢,就是我对这两份代码的研究啦,做做笔记啥的
仓库管理系统1
几个头文件
#include <cassert>
#include <iomanip>
#include <conio.h>
1.#include <cassert>
(以下有关该头文件的内容来自百度)
C++里边的assert宏在头文件CASSERT里边,主要是测试程序中这个条件:正确则不作任何操作。错误则输出信息并停止程序。
assert的作用是先计算表达式expression,如果其值为假(即为0),那么它先向标准错误流stderr打印一条出错信息,然后通过调用abort来终止程序运行;否则,assert()无任何作用。宏assert()一般用于确认程序的正常操作,其中表达式构造无错时才为真值。完成调试后,不必从源代码中删除assert()语句,因为宏NDEBUG有定义时,宏assert()的定义为空。
看了这么多,assert只在debug模式下使用,具体方式如上。(但我一直不会debug好烦)
2.#include <iomanip>
(这部分来自这里)
这个头文件用于格式化输入,比如小数点精度这些的
有这三种:
setw
setw( n ) 设域宽为n个字符
这个控制符的意思是保证输出宽度为n。
比如
cout << setw( 3 ) << 1 << setw( 3 ) << 10 << setw( 3 ) << 100 << endl; 输出结果为
_ _1_10100 (默认是右对齐)当输出长度大于3时(<<1000),setw(3)不起作用。
(_这个是指空格噢)
setprecision
使用setprecision(n)可控制输出流显示浮点数的数字个数。C++默认的流输出数值有效位是6。
使用示例如下:
#include<iomanip>
#include<iostream>
using namespace std;
int main(){
double a = 1.123456789;
cout<<a<<endl;
cout<<setprecision(3)<<a<<endl;//有效数字为两位
}
如果setprecision(n)与setiosflags合用
setiosflags(ios::fixed) 固定的浮点显示
setiosflags(ios::scientific) 指数表示
setiosflags(ios::left) 左对齐
setiosflags(ios::right) 右对齐
setiosflags(ios::skipws) 忽略前导空白
setiosflags(ios::uppercase) 16进制数大写输出
setiosflags(ios::lowercase) 16进制小写输出
setiosflags(ios::showpoint) 强制显示小数点
setiosflags(ios::showpos) 强制显示符号
emmm这一点,,,以后再详细查吧,应该和我现在写的关系不太大吧。。。
setfill
setfill(char c) 用法 : 就是在预设宽度中如果已存在没用完的宽度大小,则用设置的字符c填充
如 cout<<setfill(‘@‘)<<setw(5)<<255<<endl;
结果是:
@@255
应当指出,setw只作用于紧随其后的部分,例如
cout<<setfill(’’)<<setw(6)<<123<<456;的运行结果为*123456,这里setfill(’’)<<setw(6)只对 123 起作用输出了***123,456作为另一部分随后输出。
3.#include<conio.h>
这个是搜狗上面的答案,我觉得很乱不想整理,有需要可以直接点开看呀~
system(“pause”);
复制了这个博主的
在编写的c++程序中,如果是窗口,有时会一闪就消失了,如果不想让其消失,在程序结尾处添加:
system(“pause”);
注意:不要再return 的语句之后加,那样就执行不到了。
分析:
system() 是调用系统命令;
pause 暂停命令;
这样在运行到此处时,会显示“Press any key to continue . . .” 也就是 “按任意键继续…”;
在VC 6.0下,要添加如下的头文件!
include <stdlib.h>
getch()
关于这个函数,都在这里了
getch()功能与用法
getch(),getche(),getchar()的区别 (综合转)
我这次整体看了一下我搜到的仓库管理系统1,发现差不多可以看懂欸!!兴奋!
就只有文件的那部分可能要花点时间!下午要开始打码啦!
还要在这里标记一下,我还没有看懂他那个函数call()的意思;