技术标签: 文档 null mfc 数据库 delete sql
主要内容:
?
?
?
?
?
?
?
?
?
?
?
MFC的ODBC类对较复杂的ODBC
?
?
?
?
?
CDatabase类型的对象表示一个到数据源的连接,通过它可以操作数据源。
该类的成员函数如下表:
函数 |
说明 |
CDatabase |
构造一个对象 |
Close |
关闭数据源连接 |
Open |
通过一个ODBC驱动程序创建到数据源的连接 |
OpenEx |
通过一个ODBC驱动程序创建到数据源的连接 |
BeginTrans |
开始事务 |
BindParameters |
允许在调用CDatabase::ExecuteSQL前绑定参数 |
Cancel |
取消异步操作或第二条线程中的过程 |
CommitTrans |
执行事务 |
ExecuteSQL |
执行SQL语句,不返回记录 |
Rollback |
回滚事务,数据源返回先前的状态 |
该类的属性属性如下表:
属性 |
说明 |
CanTransact |
如果数据源支持事务,返回非零 |
CanUpdate |
如果CDatabase可以更新,返回非零 |
GetBookmarkPersistence |
获得书签对记录集对象的持久性 |
GetConnect |
返回ODBC连接串 |
GetCursorCommitBehavior |
获得提交事务对记录集对象的影响 |
GetCursorRollbackBehavio |
获得回滚事务对记录集对象的影响 |
GetDatabaseName |
返回当前使用的数据库名 |
IsOpen |
如果当前CDatabase对象连接到数据源,返回非零 |
SetLoginTimeout |
设置数据源连接的超时数(秒为单位) |
SetQueryTimeout |
设置查询操作的超时数(秒为单位) |
应用程序可使用多个CDatabase类型的对象。构造一个对象并调用Open()成员函数打开一个连接。接着构造CRecordset类型的对象以操作连接的数据源,构造时向记录集对象传递CDatabase类型的指针。完成使用后,用Close()成员函数销毁CDatabase类型的对象。
一般情况下并不需要直接使用CDatabase类型的对象,因为CRecordset类型的对象可以实现大多数的功能、但是在进行事务处理时,CDatabase就起到关键作用。事务(Transaction)指的是将一系列对数据源的更新放在一起,同时提交或一个都不提交,为的是确保多用户对数据源同时操作时的数据正确性。
CRecordset类操作记录集
一个CRecordset类型的对象代表从数据源选择的一组记录的集合——记录集,通过该类的方法实现对数据库中记录的各种操作。
该类常用的数据成员如下表:
成员 |
说明 |
m_hstmt |
包含记录集的ODBC陈述句柄,类型为HSTMT |
m_nFields |
包含记录集中字段数据成员的数量,类型为UNIT |
m_nParams |
包含记录集中参数数据成员的数量,类型为UNIT |
m_pDatabase |
包含一个CDatabase对象指针,通过它访问数据源 |
m_strFilter |
包含CString对象,定义SQL中WHERE子句 |
m_strSort |
包含CString对象,定义SQL中ORDER |
该类的构造方法如下表:
构造方法 |
说明 |
Close |
关闭记录集和与之相关的HSTMT |
CRecordset |
构造一个CRecordset对象 |
Open |
通过获得表或执行记录集所代表的查询来打开记录集 |
CRecordset类记录集属性如下表:
属性 |
说明 |
CanAppend |
如果新记录可以通过Addnew添加到记录集,返回非零 |
CanBookmark |
如果记录集支持书签,返回非零 |
CanRestart |
如果Requery可以被调用来再次运行记录集查询,返回非零 |
CanScroll |
如果可以在记录中回滚,返回非零 |
CanTransact |
如果数据源支持事务,返回非零 |
CanUpdate |
如果记录集可以被更新,返回非零 |
GetODBCFieldCount |
返回记录集中字段的数量 |
GetRecordCount |
返回记录集中记录的数量 |
GetSQL |
获得SQL字符串 |
GetStatus |
获得记录集的状态 |
GetTableName |
获得记录集所属的表名 |
IsBOF |
如果记录集定位在第一条记录之前,返回非零 |
IsDeleted |
如果记录集定位在一条删除的记录,返回非零 |
IsEOF |
如果记录集定位在最后一条记录之后,返回非零 |
IsOpen |
如果调用过Open函数,返回非零 |
CRecordset类更行操作如下表:
更新操作 |
说明 |
AddNew |
准备增加一条新纪录,调用Update之后完成添加 |
CancelUpdate |
取消任何未完成的更新 |
Delete |
从记录集中删除当前记录 |
Edit |
准备对当前记录进行修改,调用Update后完成修改 |
Update |
通过将新记录或编辑的数据存入数据源来完成AddNew或Edit操作 |
记录集有两种形式:snapshot(表示数据的静态视图)和dynaset(表示记录集与其他用户对数据库的更新保持同步)。
CFieldExchange类支持数据库类所使用的记录集字段交换(RFX)程式。如果使用自定义的数据类型写数据交换程式,会使用这个类。否则不会直接使用此类。RFX在记录集对象的字段数据成员与数据源中当前记录的相应字段之间交换数据。
CRecordView对象用于在控件中显示数据库记录的视图。这种视图是一种直接连到一个CRecordView对象的格式视图,它从一个对话框模板创建资源,并将CRecordView对象的字段显示在对话框模版的控件里。对象利用DDX和RFX机制,使窗体上的空间和记录集的字段值之间数据移动自动化,也就是说,用户不需要编写一行代码就可以完成简单的数据库记录查看程序。
由CException类派生,以3个继承的成员变量反映对数据库操作时的异常:
?
?
?
使用MFC
?
?
?
?
?
?
?
“New”-->”MFC
通过AppWizard创建了一个MFC
通过CDatabase类的Open函数来打开数据源,该函数原型如下:
virtual
LPCTSTR
BOOL
BOOL
LPCTSTR
BOOL
);
下面的例子表示如何打开数据源:
//在文档类中加入
//CDatabase类对象
CDatabase
//连接对象到一个数据源(没有密码),ODBC连接对话框将是中隐藏
m_pdatabase.Open(_T(“students”),
//或者也可以显示ODBC对话框,请用户提供连接信息
m_pdatabase.Open(NULL);
像程序Sample一样,通过向导生成数据库工程,不用添加代码就能实现对数据源的打开。在CRecordset类中有一个名为GetDefaultConnect()的虚函数值得注意,通过调用它可以返回默认的数据源连接(也就是在生成工程的时候所选择的数据源)来打开数据源。该函数如下:
CString
{
return
}
通过声明CRecordset记录集类的对象,再利用记录集类的Open()函数可打开记录集,从而获取数据库中表的数据。也正是在调用Open()函数后,记录集当中的成员变量得到数据源中表的字段值。Open()函数的形式如下:
virtual
UNIT
LPCTSTR
DWORD
);
其中nOpenType为打开的类型,可取只有一下4种:
?
?
?
第二个参数lpszSQL是一个CString的指针,指向以下内容之一:
?
?
?
第三个参数dwOptions为一系列选项的组合,它的默认值为None。
可以像下面这样调用Open()函数来打开记录集:
CDatabase
m_pdatabase.Open(_T(“students”),
CRecordset
Sample.Open(CRecordset::dynaset,
以上语句先用CDatabase对象打开一个数据源,之后构造记录及对象,最后记录及对象Sample以动态方式打开students表中的name字段。
下面的语句表示以全部默认方式执行记录记得打开操作:
CDatabase
m_pdatabase.Open(_T(“students”),
CRecordset
Sample.Open();
也可以像下面代码中那样打开一个表中的所有字段:
CDatabase
m_pdatabase.Open(_T(“students”),
CRecordset
Sample.Open(CRecordset::dynaset,
经过上面的操作,记录集对象的字段变量就获得了数据库中特定表中指定字段的数据。
像程序Sample一样,在向导当中选择数据源和表名。在CRecordset类中有一个名为GetDefaultSQL()的虚函数值得注意,通过调用它可以返回默认的SQL语句,用于形成记录集对象。该函数如下:
CString
{
return
}
通过向导创建工程后,程序的框架就生成出来。如果打开CRecordset的派生类CSampleSet,会发现里面已经有了5个变量:
//Field/Param
//{
{AFX_FIELD(CSampleSet,
long
CString
Long
Long
CString
//}}AFX_FIELD
这5个变量正好与要访问的表中的字段同名,并且变量的类型也与字段类型一致。这是MFC自动添加的变量,已绑定表中的字段。如果表中的字段是中文的,那么MFC会创建m_column1、m_column2等与之对应。RFX实现了这种绑定。
RFX(Record
可以在CSampleSet类的DoFieldExchange函数中看到一组组的RFX函数调用,正是通过调用它们,使CSampleSet记录集中的变量与students表中的字段对应起来。
void
{//{ {AFX_FIELD_MAP(CSampleSet)
pFX->SetFieldType(CFieldExchange::outputColumn);
RFX_Long(pFX,
RFX_Long(pFX,
RFX_Long(pFX,
RFX_Long(pFX,
RFX_Long(pFX,
//}}AFX_FIELD_MAP
}
RFX函数通常有3个参数(个别的会有4或5个)。第一个参数为一个指向CFieldExchange类对象的指针,第二个参数为数据源中的一个字段名称,第三个参数是与字段相对应的记录集中的变量名。常用的RFX函数如下表:
函数 |
数据类型 |
RFX_Bool |
BOOL |
RFX_Byte |
BYTE |
RFX_Binary |
CByteArray |
RFX_Double |
Double |
RFX_Sing |
Float |
RFX_Int |
Int |
RFX_Long |
Long |
RFX_LongBinary |
CLongBinary |
RFX_Text |
CString |
RFX_Date |
CTime |
CRecordset类对象中有两个成员变量,一个为m_strFilter(过滤字符串,负责对记录集进行过滤,返回过滤后的记录),另一个为m_strSort(排序字符串,对记录集进行排序)。
m_strFilter存放着SQL语句中WHERE子句的条件字符串,m_strSort中则存放着SQL语句中ORDER
下面的代码中向m_strFilter赋值“comment=good”,向m_strSort赋值“name”:
CRecordset
Sample.m_strFilter
Sample.m_strSort
除了直接向m_strFilter赋值外,还可以使用参数化。利用参数化可以更直观,更方便地完成条件查询任务。使用参数化的步骤如下:
首先声明参变量:
CString
CString
在构造函数中初始化参变量
age1
comment
将参变量与对应列绑定
pFX->SetFieldType(CFieldExchange::param);
pFX->Text(pFX,
pFX->Text(pFX,
最后利用参变量进行条件查询
m_pSet->m_strFilter
m_pSet->age
m_pSet->comment
m_pSet->Requery();
参变量的值按绑定的顺序替换查询字符串中的“?”适配符。代码中的m_pSet是CRecordView类的一个记录集指针,指向当前文档类中的记录集变量。它是在CRecordView类的OnInitialUpdate中被赋予文档类下记录集对象的指针的。下面是程序中CSampleView类的OnInitialUpdate函数体:
void
{ //为m_pSet赋予文档类下的记录集对象的指针
m_pSet
CRecordView::OnInitialUpdate();
ResizeParentToFit();
}
CRecordset类中有一组函数负责记录集指针的移动,例如使用记录集指针下移一个记录、使用记录集指针上移一个记录等。
1、
2、
3、
4、
5、
6、
知道上面的这些函数的意义后,下面来看如何遍历记录集。下面的代码中m_pSet是一个记录集指针,m_list为一个列表框控件(ClistBox类)的变量:
if(!m_pSet->IsOpen()) //用IsOpen函数检测记录集是否打开
m_pSet->Open();
m_pSet->MoveFirst();
while(!m_pSet->IsEOF())
{
m_list.AddString(m_pSet->m_name);
m_pSet->MoveNext();
}
m_pSet->MoveFirst(); //遍历完成后,使记录集指针指向第一条记录
当在记录集中浏览的时候,可能想返回记录集中特定的一条记录,CRecordset提供了两种方法可以指定记录集到特定的位置。
1、
可以在记录集中的某一条记录增加一个书签。在记录集浏览时由于用户的增删操作使记录的绝对位置发生改变,所以以来绝对位置是不可靠的。因此需要使用书签定位来为所想要的记录定位。CRecordset类中提供的书签定位的方法是GetBookmark和SetBookmark两个函数,他们的原型如下:
void
void
这里只需直接使用CDBVariant的对象即可。
//创建CDBVariant对象
CDBVariant
//rs是CRecordset类或CRecordset类派生类的对象
rs.GetBookmark(bookmark);
//一系列移动到其他记录的代码
rs.MoveNext();
rs.MoveNext();
rs.SetBookmark(bookmark);
GetBookmark函数将当前的记录存入一个CDBVariant的对象中,经过一系列的纪录移动之后,在调用SetBookmark,并且用刚才记录“书签”的CDBVariant对象bookmark作参数来使用当前记录集重新指向“书签”的位置。
是否支持书签定位取决于ODBC驱动程序和记录集类型。可以通过调用CRecordset::CanBookmark来确定是否支持书签定位。如果想支持书签定位,还需要在记录集的Open函数的dwOptions参数位置中加入CRecordset::useBookmarks参数。注意forward-only
这个函数的返回值为bitmask,这是一个DWORD类型的返回值。该值可以是下表中的多个bitmask值的组合。
bitmask值 |
书签的有效性 |
SQL_BP_CLOSE |
Requery操作后,书签有效 |
SQL_BP_DELETE |
对某行执行delete操作后,书签对此行依然有效 |
SQL_BP_DROP |
一次Close操作后,书签有效 |
SQL_BP_SCROLL |
任何Move操作之后,书签都有效 |
SQL_BP_TRANSACTION |
一次事务被提交或回滚后,书签有效 |
SQL_BP_UPDATE |
对某行执行Update操作后,书签对此行有效 |
SQL_BP_OTHER_HSTMT |
与某记录集对象相关的书签对另一记录集也有效 |
2、
相对于书签定位,绝对定位就好像记住某本书的某一个固定页码一样。绝对定位就是通过原始的记录位置来设置当前记录,比如可以设置记录集中第8条记录为当前记录。如想使用绝对定位来改变当前的记录集位置,可以调用CRecordset::SetAbsolutePosition函数。其原型为:
void
nRows表示记录集中的一个绝对位置。调用该函数会把记录集指针定位到nRows参数所指行号的记录上。
下面的代码表示把记录集定位到第12条记录的位置上:
long
row
rs.SetAbsolutePositon(row);
对于ODBC的记录集来说,绝对位置1指的是记录集当中的第一条记录,绝对位置如果是0则代表的是BOF位置(在第一条记录之前)。
(***forward-only
通过在对话框上添加控件,并且为控件绑定变量来达到数据交换并显示的目的,与控件绑定的变量正是记录集中的那些字段变量。步骤如下:
l
l
l
到底记录集中的变量是如何把数据显示在控件上呢?下面讲述DDX技术。
DDX是Dialog
CRecordView类里面有一个DoDataExchange函数,所有的DDX函数都是在DoDataExchange中调用的。DoDataExchange函数为DDX函数提供了一个CDataExchange类对象的指针。在工程刚刚创建时,CSampleView::DodataExchange函数是一个空函数,因此此时对话框上并没有控件,更没有与控件对应的变量。但经过窗体添加控件、为控件添加变量之后,再打开DoDataExchange函数,将会出现下面这样的代码:
void
{
CRecordView::DoDataExchange(pDX);
//{ {AFX_DATA_MAP(CSampleView)
DDX_FieldText(pDX,
DDX_FieldText(pDX,
DDX_FieldText(pDX,
DDX_FieldText(pDX,
DDX_FieldText(pDX,
//}}AFX_DATA_MAP
}
DDX_FieldText函数负责在对话框控件和记录集中字段变量之间建立联系。因为记录集中的字段变量对应的是数据库中表的每个字段,所以就能在控件上看到表中的数据了。DDX函数有四个参数,分别为:
l
l
l
l
DDX可以管理以下类型数据变量与控件的数据交换。它们是short、long、int、DWORD、CString、float、double、BOOL以及BYTE。
程序通过UpdateData这个函数在控件与变量之间达到双向数据,而不是直接调用DoDataExchange。UpdateData函数的原型如下:
BOOL
bSaveAndValidate指示了数据传输的方向,当为TRUE时就是控件向变量传输。反之,就是变量向控件传输数据。默认值为TRUE
对记录的操作大多数都是由CRecordset类来负责的,执行添加的任务也不例外。CRecordset类中的函数AddNew()表示向表中添加一条新的纪录,该函数原型如下:
virtual
执行AddNew()函数之后会新增加一条空记录,等待输入数据。此时记录的每一个字段都被初始化NULL。在输入新的记录数据之后,需调用另一个CRecordset类的函数才能完成对新记录的添加,这个函数是Update(),函数原型为:virtual
在调用完AddNew函数、输入新数据之后一定要调用Update,它负责把新添加的数据保存到数据源。实际上AddNew函数只是在内存中创建了一块缓冲区,等待输入数据,之后需要使用Update来真正把数据存入数据源。如果在调用Update之前滚动到了另一条记录,那么新记录就会丢失,也不会提出警告。对于dynaset(动态集)类型的记录集,新记录会添加到末尾。新记录不能被添加到Snapshot类型的记录集中。最后还需要调用CRecordset::Requery函数以刷新记录集:virtual
Requery函数负责刷新记录集来反映当前最新的数据。在每次对记录进行添加、删除后,都有必要调用Requery来更新记录集。调用Requery函数后,记录集指针重新指向第一条记录。
下面的代码实现了在一个名为OnAdd的函数中添加记录:
void
{
//添加一条新记录
m_pSet->AddNew();
//对记录集中的m_id、m_name、m_department、m_age等赋值
m_pSet->m_id
m_pSet->m_name
m_pSet->m_department
m_pSet->m_age
m_pSet->m_comment
//更新记录集,将新记录存入数据源
m_pSet->Update();
//刷新记录集,并使记录集指针回到第一条记录
m_pSet->Requery();
}
调用CRecordset类中的Delete函数进行删除记录。该函数用于删除当前记录集指针指向的记录。原型如下:virtual
一次成功的删除后,被删除记录的字段全部被设为NULL,必须调用Move函数移动到其他记录上来一处被删除的记录。如果删除不成功,记录中的数据也不会被破坏。一旦移除了删除的记录,就再也不能返回他了。在调用Delete函数时,记录集中必须有一条有效的记录,否则会产生错误。。如果Delete了一条记录,但没有Move到另一条记录就有进行了Delete操作,Delete会产生一个CDBException类的错误。
下面的代码在一个名为OnDelete的函数中实现了删除当前记录的操作:
void
{
//删除当前记录
m_pSet->Delete();
//刷新记录集
m_pSet->Requery();
}
CRecordset::Edit函数的作用是允许修改当前的记录。原型如下:
virtual
调用Edit之后,就可以直接重新设定当前记录中每个字段的值了。再重新设定之后,还需要调用Update函数来保存对数据的修改。实际上,调用Edit之后,要被修改的值先被保存起来。如果Edit之后没有Update,而是移动到另一条记录,那么记录以前的值被重新恢复,不对记录作出修改。或者,调用了一次Edit,而对记录也作出了修改,然后又调用了一次Edit,那么记录还是被恢复到第一次调用Edit之前的值。
下面的代码在名为OnEdit的函数中实现对数据的编辑:
void
{
m_pSet->Edit();
m_pSet->m_id
m_pSet->m_name
m_pSet->m_department
m_pSet->m_age
m_pSet->m_comment
m_pSet->Update();
m_pSet->Requery();
}
并不是所有的ODBC功能都被数据库类所支持,所以有时候需要使用直接执行SQL语句来对数据库进行一些操作。
CDatabase类中有一个函数ExecuteSQL,通过它可以直接执行SQL语句,对数据库进行操作。原型如下:void
参数lpszSQL是一个CString类型的指针,包含一条可执行的、有效地SQL命令。这个函数并不返回信息,如果要对记录进行操作,那么还是要使用记录集对象。
下面的代码可以在一个名为class的表中增加一条记录。m_database是一个CDatabase类的对象。VALUES中是新增记录的具体值,分别于表中的每一个字段相对应。
m_pSet->Open();
m_pSet->AddNew();
m_database.ExecuteSQL(“insert
m_pSet.Update();
m_pSet->Edit();
m_database.ExecuteSQL(“Delete
m_pSet.Update();
事务操作涉及CDatabase类的几个成员函数,BeginTrans表示开始事务,CommitTrans表示接受所有对数据源的修改,或者调用Rollback来终止整个事务。执行事务的三个步骤:
l
l
l
下面的代码中要删除一家商店中的一项商品,因为要将两个记录集中涉及该商品的所有记录同时删除,所以要使用事务处理。记录集orderset为订单记录,记录集goodsset为商品品种记录。m_shop为CDatabase类对象,假设它已经连接到了数据源。strgoodsID为用户输入的要删除商品的ID。两个记录集中都使用m_strFilter变量来过滤出要删除的记录。
BOOL
{ //开始事务
if(!m_shop.BeginTrans())
return
//创建订单记录集
COrderSet
orderset.m_strFilter
if(!orderset.Open(CRecordset::dynaset))
return
//创建商品记录集
CGoodsSet
goodsset.m_strFilter
if(!goodsset.Open(CRecordset::dynaset))
return
//操作中使用了try…catch()来捕获错误信息
//因为有时会经常出现一些意想不到的错误
TRY
{ //删除订单记录
while(!orderSet.IsEOF())
{
orderset.Delete();
orderset.MoveNext();
}
//删除商品条目
goodsset.Delete();
//执行事务
m_shop.CommitTrans();
}
CATCH_ALL(e)
{ //取消事务
m_shop.Rollback();
return
}
END_CATCH_ALL
//关闭记录集
orderset.Close();
goodsset.Close();
return
}
有时候需要使用多个记录集,以使在一个程序中可以操作多个表。生成工程时,通常只选择一个表作为记录集要对应的对象。而且就算在生成工程时选择多个表,那么AppWizard也只会产生多个表的一个笛卡尔乘积,并不会为每一个表产生一个记录集。
通过Visual
“View”
文章浏览阅读1.6k次。安装配置gi、安装数据库软件、dbca建库见下:http://blog.csdn.net/kadwf123/article/details/784299611、检查集群节点及状态:[root@rac2 ~]# olsnodes -srac1 Activerac2 Activerac3 Activerac4 Active[root@rac2 ~]_12c查看crs状态
文章浏览阅读1.3w次,点赞45次,收藏99次。我个人用的是anaconda3的一个python集成环境,自带jupyter notebook,但在我打开jupyter notebook界面后,却找不到对应的虚拟环境,原来是jupyter notebook只是通用于下载anaconda时自带的环境,其他环境要想使用必须手动下载一些库:1.首先进入到自己创建的虚拟环境(pytorch是虚拟环境的名字)activate pytorch2.在该环境下下载这个库conda install ipykernelconda install nb__jupyter没有pytorch环境
文章浏览阅读5.2k次,点赞19次,收藏28次。选择scoop纯属意外,也是无奈,因为电脑用户被锁了管理员权限,所有exe安装程序都无法安装,只可以用绿色软件,最后被我发现scoop,省去了到处下载XXX绿色版的烦恼,当然scoop里需要管理员权限的软件也跟我无缘了(譬如everything)。推荐添加dorado这个bucket镜像,里面很多中文软件,但是部分国外的软件下载地址在github,可能无法下载。以上两个是官方bucket的国内镜像,所有软件建议优先从这里下载。上面可以看到很多bucket以及软件数。如果官网登陆不了可以试一下以下方式。_scoop-cn
文章浏览阅读4.5k次,点赞2次,收藏3次。首先要有一个color-picker组件 <el-color-picker v-model="headcolor"></el-color-picker>在data里面data() { return {headcolor: ’ #278add ’ //这里可以选择一个默认的颜色} }然后在你想要改变颜色的地方用v-bind绑定就好了,例如:这里的:sty..._vue el-color-picker
文章浏览阅读640次。基于芯片日益增长的问题,所以内核开发者们引入了新的方法,就是在内核中只保留函数,而数据则不包含,由用户(应用程序员)自己把数据按照规定的格式编写,并放在约定的地方,为了不占用过多的内存,还要求数据以根精简的方式编写。boot启动时,传参给内核,告诉内核设备树文件和kernel的位置,内核启动时根据地址去找到设备树文件,再利用专用的编译器去反编译dtb文件,将dtb还原成数据结构,以供驱动的函数去调用。firmware是三星的一个固件的设备信息,因为找不到固件,所以内核启动不成功。_exynos 4412 刷机
文章浏览阅读2w次,点赞24次,收藏42次。Linux系统配置jdkLinux学习教程,Linux入门教程(超详细)_linux配置jdk
文章浏览阅读3.3k次,点赞5次,收藏19次。xlabel('\delta');ylabel('AUC');具体符号的对照表参照下图:_matlab微米怎么输入
文章浏览阅读119次。顺序读写指的是按照文件中数据的顺序进行读取或写入。对于文本文件,可以使用fgets、fputs、fscanf、fprintf等函数进行顺序读写。在C语言中,对文件的操作通常涉及文件的打开、读写以及关闭。文件的打开使用fopen函数,而关闭则使用fclose函数。在C语言中,可以使用fread和fwrite函数进行二进制读写。 Biaoge 于2024-03-09 23:51发布 阅读量:7 ️文章类型:【 C语言程序设计 】在C语言中,用于打开文件的函数是____,用于关闭文件的函数是____。
文章浏览阅读3.4k次,点赞2次,收藏13次。跟随鼠标移动的粒子以grid(SOP)为partical(SOP)的资源模板,调整后连接【Geo组合+point spirit(MAT)】,在连接【feedback组合】适当调整。影响粒子动态的节点【metaball(SOP)+force(SOP)】添加mouse in(CHOP)鼠标位置到metaball的坐标,实现鼠标影响。..._touchdesigner怎么让一个模型跟着鼠标移动
文章浏览阅读178次。项目运行环境配置:Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。项目技术:Springboot + mybatis + Maven +mysql5.7或8.0+html+css+js等等组成,B/S模式 + Maven管理等等。环境需要1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。_基于java技术的停车场管理系统实现与设计
文章浏览阅读3.5k次。前言对于MediaPlayer播放器的源码分析内容相对来说比较多,会从Java-&amp;gt;Jni-&amp;gt;C/C++慢慢分析,后面会慢慢更新。另外,博客只作为自己学习记录的一种方式,对于其他的不过多的评论。MediaPlayerDemopublic class MainActivity extends AppCompatActivity implements SurfaceHolder.Cal..._android多媒体播放源码分析 时序图
文章浏览阅读2.4k次,点赞41次,收藏13次。java 数据结构与算法 ——快速排序法_快速排序法