Resive world

Come world to Record life


  • Home

  • Tags

  • Categories

  • Archives

  • Sitemap

  • Search

Qt中使用标准输入框

Posted on 2015-10-25 | In Qt

这一节主要讲一下标准输入框的使用,Qt提供了一个QInputDialog类,这个类提供了几个预先设定好的常用输入对话框。
比如:

  • 需要输入文本的时候,他将QlineEdit的一系列控件封装到QInputDialog::getText()中;
  • 需要输入选择条目的时候,他将QComboBox的一系列控件封装到QInputDialog::getItem()中;
  • 需要输入数值的时候,他将QSpinbox的一系列控件封装到QInputDialog::getInt()或QInputDialog::getDouble()中。

以下依旧是用程序来说明:

Dialog.pro

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#-------------------------------------------------
#
# Project created by QtCreator 2015-10-24T17:32:35
#
#-------------------------------------------------

QT += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = Dialog
TEMPLATE = app

SOURCES += main.cpp
dialog.cpp

HEADERS += dialog.h

dialog.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include<QGridLayout>
#include<QPushButton>
#include<QLabel>
#include<QInputDialog>
class Dialog : public QDialog
{
Q_OBJECT

public:
Dialog(QWidget *parent = 0);
~Dialog();
public:
QGridLayout *layout;
QPushButton *nameButton,*sexButton,*ageButton,*statureButton;
QLabel *label1,*label2,*label3,*label4,*nameLabel,*sexLabel,*ageLabel,*statureLabel;
private slots:
//设置按钮单击信号的槽
void slotName();
void slotSex();
void slotAge();
void slotStature();
};

#endif // DIALOG_H

dialog.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#include "dialog.h"

Dialog::Dialog(QWidget *parent)
: QDialog(parent)
{
setWindowTitle("Input Dialog");
label1=new QLabel("姓名:");
label2=new QLabel("性别:");
label3=new QLabel("年龄:");
label4=new QLabel("身高:");

//创建显示标签,用于显示已选择的信息。
nameLabel=new QLabel("LiMing");
/**

以下调用了QLabel的setFrameStyle()方法,设置QLabel的样式,这里有两个枚举类型--QFrame::Shape和QFrame::Shadow

QFrame::Shape定义了QFrame的框架所使用的外形。当前定义的效果有:

QFrame::NoFrame 不画任何东西
QFrame::Box 在它的内容周围画一个框
QFrame::Panel 画一个平板使内容看起来凸起或者凹陷
QFrame::WinPanel 像Panel,但QFrame绘制三维效果的方式和Microsoft Windows 95(及其它)的一样
QFrame::ToolBarPanel 调用QStyle::drawToolBarPanel()
QFrame::MenuBarPanel 调用QStyle::drawMenuBarPanel()
QFrame::HLine 绘制一个水平线,但没有框任何东西(作为分隔是有用的)
QFrame::VLine 绘制一个竖直线,但没有框任何东西(作为分隔是有用的)
QFrame::StyledPanel 调用QStyle::drawPanel()
QFrame::PopupPanel 调用QStyle::drawPopupPanel()

QFrame::Shadow这个枚举类型定义了QFrame的框架所使用的外形。当前定义的效果有:

QFrame::Plain 框架和内容看来和周围一样高
QFrame::Raised 框架和内容看起来凸起
QFrame::Sunken 框架和内容看起来凹陷
QFrame::MShadow 内部的,对于阴影的掩码

*/

nameLabel->setFrameStyle(QFrame::Panel|QFrame::Sunken);//这里设置了凹陷的效果
sexLabel=new QLabel("man");
sexLabel->setFrameStyle(QFrame::Panel|QFrame::Sunken);
ageLabel=new QLabel("20");
ageLabel->setFrameStyle(QFrame::Panel|QFrame::Sunken);
statureLabel=new QLabel("178");
statureLabel->setFrameStyle(QFrame::Panel|QFrame::Sunken);

nameButton=new QPushButton;
nameButton->setText("...");
sexButton=new QPushButton;
sexButton->setText("...");
ageButton=new QPushButton;
ageButton->setText("...");
statureButton=new QPushButton;
statureButton->setText("...");

layout=new QGridLayout(this);
layout->addWidget(label1,0,0);
layout->addWidget(nameLabel,0,1);
layout->addWidget(nameButton,0,2);
layout->addWidget(label2,1,0);
layout->addWidget(sexLabel,1,1);
layout->addWidget(sexButton,1,2);
layout->addWidget(label3,2,0);
layout->addWidget(ageLabel,2,1);
layout->addWidget(ageButton,2,2);
layout->addWidget(label4,3,0);
layout->addWidget(statureLabel,3,1);
layout->addWidget(statureButton,3,2);

//设置各个Grid列的相对比例,这里是1:4:2
layout->setColumnStretch(0,1);
layout->setColumnStretch(1,4);
layout->setColumnStretch(2,1);

layout->setMargin(10);
//设置窗口的固定大小
this->setFixedSize(300,120);

connect(nameButton,SIGNAL(clicked()),this,SLOT(slotName()));
connect(sexButton,SIGNAL(clicked()),this,SLOT(slotSex()));
connect(ageButton,SIGNAL(clicked()),this,SLOT(slotAge()));
connect(statureButton,SIGNAL(clicked()),this,SLOT(slotStature()));
}

Dialog::~Dialog()
{

}

void Dialog::slotName(){
bool ok;

/*
static QString QInputDialog::getText ( QWidget * parent,const QString & title,const QString &label, QLineEdit::EchoMode mode = QLineEdit::Normal,const QString & text = QString(), bool * ok = 0, Qt::WindowFlags flags = 0 );

第一个参数parent,也就是那个熟悉的父组件的指针;
第二个参数title就是对话框的标题;
第三个参数label是在输入框上面的提示语句;
第四个参数mode用于指明这个QLineEdit的输入模式,取值范围是QLineEdit::EchoMode,默认是Normal,也就是正常显示,你也可以声明为password,这样就是密码的输入显示了;
第五个参数text是QLineEdit的默认字符串;
第六个参数 ok是可选的,如果非NLL,则当用户按下对话框的OK按钮时,这个bool变量会被置为true,可以由这个去判断用户是按下的OK还是Cancel,从而获知这个text是不是有意义;
第七个参数flags用于指定对话框的样式。
*/

QString name=QInputDialog::getText(this,"Username","Please input the name:",QLineEdit::Normal,nameLabel->text(),&ok);
if(ok&&!name.isEmpty()){
nameLabel->setText(name);
}
}

void Dialog::slotSex(){
QStringList list;
list<<"male"<<"female";//给QStringList 赋值
bool ok;

/*
static QString QInputDialog::getText ( QWidget * parent,const QString & title,const QString &label, const QStringList &list,int current=0,bool editable=true, bool * ok = 0, Qt::WindowFlags flags = 0 );

第一个参数parent,也就是那个熟悉的父组件的指针;
第二个参数title就是对话框的标题;
第三个参数label是在输入框上面的提示语句;
第四个参数QStringList用于指定需要显示的条目是一个QStringList 对象,
第五个参数current是QStringList 中默认的条目的下标;
第六个参数editable是设置文字是否可以编辑
第七个参数 ok是可选的,如果非NLL,则当用户按下对话框的OK按钮时,这个bool变量会被置为true,可以由这个去判断用户是按下的OK还是Cancel,从而获知这个text是不是有意义;
第八个参数flags用于指定对话框的样式。
*/
QString sex=QInputDialog::getItem(this,"Sex","Please choose the sex",list,0,false,&ok);
if(ok){
sexLabel->setText(sex);
}
}

void Dialog::slotAge(){
bool ok;
/*
static QString QInputDialog::getText ( QWidget * parent,const QString & title,const QString &label, int value ,int minValue=-2147483647, int maxValue = 2147483647, int step=1, bool * ok = 0, Qt::WindowFlags flags = 0 );

第一个参数parent,也就是那个熟悉的父组件的指针
第二个参数title就是对话框的标题
第三个参数label是在输入框上面的提示语句
第四个参数value表示默认值
第五个参数minValue表示最小值
第六个参数maxValue表示最大值
第七个参数step表示各个选项的间隔
第八个参数ok是可选的,如果非NLL,则当用户按下对话框的OK按钮时,这个bool变量会被置为true,可以由这个去判断用户是按下的OK还是Cancel,从而获知这个text是不是有意义;
第九个参数flags用于指定对话框的样式。
*/

int age=QInputDialog::getInt(this,"User age","Please input the age",ageLabel->text().toInt(),0,150,1,&ok);
if(ok){
ageLabel->setText(QString().setNum(age));//将数字变成文本
}
}

void Dialog::slotStature(){
bool ok;

//QInputDialog::getDouble使用方法如getInt
double stature=QInputDialog::getDouble(this,"User stature","Please input the stature",statureLabel->text().toDouble(),0,240.00,1,&ok);//这里文本变成double要进行转换
if(ok){
statureLabel->setText(QString().setNum(stature));
}
}

main.cpp

1
2
3
4
5
6
7
8
9
10
11
#include "dialog.h"
#include <QApplication>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Dialog w;
w.show();

return a.exec();
}

运行截图





Qt各类位置信息函数

Posted on 2015-10-24 | In Qt

本节主要演示获取窗口位置以及显示区域坐标以及大小的函数,分析其中的区别,主要是 x(),y(),frameGeometry(),pos(),geometry(),width(),height(),rect(),size()函数,这些函数是由QWidget 提供。

以下是演示的工程源码,具体分析结合在源码中。

Dialog.pro(必备)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#-------------------------------------------------
#
# Project created by QtCreator 2015-10-24T17:32:35
#
#-------------------------------------------------

QT += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = Dialog
TEMPLATE = app

SOURCES += main.cpp
dialog.cpp

HEADERS += dialog.h

dialog.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include<QLabel>
#include<QGridLayout>
class Dialog : public QDialog
{
Q_OBJECT

public:
Dialog(QWidget *parent = 0);
~Dialog();
public:
//基本的布局
QGridLayout *layout;
QLabel *xLabel,*yLabel,*frameGeometryLabel,*posLabel,*geometryLabel,*widthLabel,*heightLabel,*rectLabel,*sizeLabel;
QLabel *xLabelv,*yLabelv,*frameGeometryLabelv,*posLabelv,*geometryLabelv,*widthLabelv,*heightLabelv,*rectLabelv,*sizeLabelv;
//刷新时调用的函数
void updateLabel();
protected:
//以下是继承自QWidget的函数,分别响应对话框移动事件和对话框大小调整事件
void moveEvent(QMoveEvent *);
void resizeEvent(QResizeEvent *);
};

#endif // DIALOG_H

dialog.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#include "dialog.h"

Dialog::Dialog(QWidget *parent)
: QDialog(parent)
{
//基本布局
setWindowTitle("Show position");
layout=new QGridLayout(this);
xLabel=new QLabel;
xLabel->setText("x():");
yLabel=new QLabel;
yLabel->setText("y():");
frameGeometryLabel=new QLabel;
frameGeometryLabel->setText("frameGeometry():");
posLabel=new QLabel;
posLabel->setText("pos():");
geometryLabel=new QLabel;
geometryLabel->setText("geometry():");
widthLabel=new QLabel;
widthLabel->setText("width():");
heightLabel=new QLabel;
heightLabel->setText("height():");
rectLabel=new QLabel;
rectLabel->setText("rect():");
sizeLabel=new QLabel;
sizeLabel->setText("size():");

xLabelv=new QLabel;
yLabelv=new QLabel;
frameGeometryLabelv=new QLabel;
posLabelv=new QLabel;
geometryLabelv=new QLabel;
widthLabelv=new QLabel;
heightLabelv=new QLabel;
rectLabelv=new QLabel;
sizeLabelv=new QLabel;

layout->addWidget(xLabel,0,0);
layout->addWidget(xLabelv,0,1);
layout->addWidget(yLabel,1,0);
layout->addWidget(yLabelv,1,1);
layout->addWidget(frameGeometryLabel,2,0);
layout->addWidget(frameGeometryLabelv,2,1);
layout->addWidget(posLabel,3,0);
layout->addWidget(posLabelv,3,1);
layout->addWidget(geometryLabel,4,0);
layout->addWidget(geometryLabelv,4,1);
layout->addWidget(widthLabel,5,0);
layout->addWidget(widthLabelv,5,1);
layout->addWidget(heightLabel,6,0);
layout->addWidget(heightLabelv,6,1);
layout->addWidget(rectLabel,7,0);
layout->addWidget(rectLabelv,7,1);
layout->addWidget(sizeLabel,8,0);
layout->addWidget(sizeLabelv,8,1);
updateLabel();
}

Dialog::~Dialog()
{

}

void Dialog::updateLabel(){
//调用QString匿名对象的setNum()方法将int转化为QString
xLabelv->setText(QString().setNum(x()));
yLabelv->setText(QString().setNum(y()));

QString tmp;
tmp=QString().setNum(frameGeometry().x())+","+
QString().setNum(frameGeometry().y())+","+
QString().setNum(frameGeometry().width())+","+
QString().setNum(frameGeometry().height());
frameGeometryLabelv->setText(tmp);

tmp=QString().setNum(pos().x())+","+
QString().setNum(pos().y());
posLabelv->setText(tmp);

tmp=QString().setNum(geometry().x())+","+
QString().setNum(geometry().y())+","+
QString().setNum(geometry().width())+","+
QString().setNum(geometry().height());
geometryLabelv->setText(tmp);

widthLabelv->setText(QString().setNum(width()));
heightLabelv->setText(QString().setNum(height()));

tmp=QString().setNum(rect().x())+","+
QString().setNum(rect().y())+","+
QString().setNum(rect().width())+","+
QString().setNum(rect().height());
rectLabelv->setText(tmp);

tmp=QString().setNum(size().width())+","+QString().setNum(size().height());
sizeLabelv->setText(tmp);
}

void Dialog::moveEvent(QMoveEvent *){
updateLabel();
}

void Dialog::resizeEvent(QResizeEvent *){
updateLabel();
}

main.cpp

1
2
3
4
5
6
7
8
9
10
#include "dialog.h"
#include <QApplication>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Dialog w;
w.show();
return a.exec();
}

程序截图

各个函数的意义简图

Qt标准对话框的使用

Posted on 2015-10-24 | In Qt

学习编程个人觉得还是得从代码谈起,一方面有利于加深理解,另一方面也方便使(摘)用(抄)。

这一节只要是理解简单的对话框的编写框架和一些基本的标准对话框的使用方法。一些具体的说明将在源码中分析。

Dialog.pro(Qt的基本文件)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#-------------------------------------------------
#
# Project created by QtCreator 2015-10-24T17:38:36
#
#-------------------------------------------------

QT += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = DIalog
TEMPLATE = app

SOURCES += main.cpp
dialog.cpp

HEADERS += dialog.h

dialog.h(对话框类的声明)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#ifndef DIALOG_H
#define DIALOG_H
#include<QApplication>
#include <QDialog>
#include<QGridLayout>
#include<QPushButton>
#include<QLineEdit>
#include<QFrame>
#include<QString>
#include<QFileDialog>
#include<QColor>
#include<QColorDialog>
#include<QFont>
#include<QFontDialog>
class Dialog : public QDialog
{
Q_OBJECT

public:
Dialog(QWidget *parent = 0);
~Dialog();
public://以下是使用到的控件的声明
QGridLayout *layout;
QPushButton *filePushButton,*colorPushButton,*fontPushButton;
QLineEdit *fileLineEdit,*fontLineEdit;
QFrame *colorFrame;
private slots://以下是用到的槽,各对应一个信号(事件)
void slotOpenFileDlg();
void slotOpenColorDlg();
void slotOpenFontDlg();
};

#endif // DIALOG_H

dialog.cpp(类的实现---重要---)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include "dialog.h"

Dialog::Dialog(QWidget *parent)
: QDialog(parent)
{

setWindowTitle(tr("This is the title."));//设置对话框标题,这里有个tr()函数,用途好像是为了实现国际化的一个翻译函数。。。不太懂,不过目测问题挺多的,小规模的程序感觉没什么必要用,以后就不用这个了。

layout=new QGridLayout(this);//这句是把当前的布局交给layout来表示

//创建按钮控件并设置Text属性
filePushButton =new QPushButton;
filePushButton->setText("File Dialog");
colorPushButton=new QPushButton;
colorPushButton->setText("Color Dialog");
fontPushButton=new QPushButton;
fontPushButton->setText("Font Dialog");

fileLineEdit =new QLineEdit; //QLineEdit类代表编辑框,它可以让用户输入一个单行文本。

//QFrame 类,这个姑且用来显示当前选择的颜色
colorFrame=new QFrame;
colorFrame->setFrameShape(QFrame::Box);//设置来自框架风格的框架外形值,一般就这个。
colorFrame->setAutoFillBackground(true);//是否自动刷新填充色,这里我们需要设为true

   //文本编辑框,用来显示样例字体
fontLineEdit=new QLineEdit;
fontLineEdit->setText("Hello world.");

   //设置布局,这里是GridLayout,用addWidget方法设置控件的相对位置
layout->addWidget(filePushButton,0,0);
layout->addWidget(fileLineEdit,0,1);
layout->addWidget(colorPushButton,1,0);
layout->addWidget(colorFrame,1,1);
layout->addWidget(fontPushButton,2,0);
layout->addWidget(fontLineEdit,2,1);
layout->setMargin(15);//设置到上下左右边界的距离
layout->setSpacing(10);//设置各个控件之间的空隙

   //信号和槽的连接,连接各个按钮的点击事件
connect(filePushButton,SIGNAL(clicked()),this,SLOT(slotOpenFileDlg()));
connect(colorPushButton,SIGNAL(clicked()),this,SLOT(slotOpenColorDlg()));
connect(fontPushButton,SIGNAL(clicked()),this,SLOT(slotOpenFontDlg()));
}

Dialog::~Dialog()
{

}

//打开标准文件选择对话框
void Dialog::slotOpenFileDlg(){
//传入句柄,标题,默认目录,文件类型(多种文件的话用;;分开),返回选择的文件名,或者一个空串
QString s=QFileDialog::getOpenFileName(this,"open file dialog","/","C++ files(*.cpp);;C files(*.c)");
fileLineEdit->setText(s);//将文件名交给编辑框
}

//打开标准颜色选择对话框
void Dialog::slotOpenColorDlg(){
//getColor方法会打开一个颜色选择对话框,传入默认的颜色,返回选择的颜色。
QColor color=QColorDialog::getColor(Qt::blue);
if(color.isValid()){//判断颜色是否合法
colorFrame->setPalette(QPalette(color));//将Frame的背景色设置为选择的颜色
}
}

//打开标准字体对话框
void Dialog::slotOpenFontDlg(){
bool ok;
   //getFont方法打开一个字体选择对话框,返回选择的字体,同时以引用的方式返回字体是否合法。
QFont font=QFontDialog::getFont(&ok);
if(ok){//判断字体是否合法
fontLineEdit->setFont(font);//设置编辑框的字体
}
}

vsftp服务的搭建和配置(2/2)

Posted on 2015-10-23 | In Linux

配置本地用户

  1. 在配置文件中添加local_enable=YES表示允许以本地用户登陆。这是必须的。
  2. 然而默认情况下登陆后只有读取权限没有写入权限,所以如果需要能够上传文件,则需要添加write_enable=YES 。并且保证登陆的用户有相应的权限。
  3. 有时候不希望让登陆的用户看见不属于他家目录里的东西,这时候就需要将该用户’chroot’,需要添加chroot_local_user=YES ,或者:
    1
    2
    3
    chroot_local_user=YES
    chroot_list_enable=YES
    chroot_list_file=/etc/vsftpd.chroot_list#这个可以自定义

通过编辑/etc/vsftpd.chroot_list来精确控制chroot的权限。

但是这样设置有时候在登陆的时候出现refusing to run with writable root inside chroot 错误,这是因为系统不允许chroot 用户有写入自身的权限,所以如果这样设置就不能给该用户写权限了,需要取消他对自身家目录的写入权限:

1
root@iZ28ntr2ej5Z:/home# chmod g-w stu

(在配置了chroot_local_user=YES之后一定要注意,所有拥有w权限的用户将无法登录!!!所以。。如果想设置多个用户,其中某些我们想让他拥有w权限,而另一些只拥有r权限的话,还是要配置一下chroot_list_file 为好)

配置匿名用户

1
2
3
4
5
6
7
8
9
10
11
12
13
14
anonymous_enable=YES            #是否启用匿名用户
no_anon_password=YES    #匿名用户login时不询问口令

#下面这四个主要语句控制这文件和文件夹的上传、下载、创建、删除和重命名。
anon_upload_enable=(YES/NO); #控制匿名用户对文件(非目录)上传权限。
anon_world_readable_only=(YES/NO); #控制匿名用户对文件的下载权限
anon_mkdir_write_enable=(YES/NO); #控制匿名用户对文件夹的创建权限
anon_other_write_enable=(YES/NO); #控制匿名用户对文件和文件夹的删除和重命名

#匿名用户下载是使用的是nobody这个用户,所以相应的O这个位置要有R权限才能被下载。若想让匿名用户能上传和删除权限,必需设置write_enable=YES #全局设置,是否容许写入(无论是匿名用户还是本地用户,若要启用上传权限的话,就要开启他)
anon_root=(none) #匿名用户主目录
anon_max_rate=(0) #匿名用户速度限制
chown_uploads=YES #所有匿名上传的文件的所属用户将会被更改成chown_username
chown_username=whoever #匿名上传文件所属用户名

由于一般情况下懒得弄这个匿名,所以以上设置并没有实践确认,权且留下来备用。

文件的定义

1
2
3
4
5
6
7
8
9
chroot_list_file=/etc/vsftpd/vsftpd.chroot_list #定义限制/允许更改用户主目录的文件
userlist_file=/etc/vsftpd/vsftpd.user_list #定义限制/允许用户登录的文件
banner_file=/etc/vsftpd/banner #定义登录信息文件的位置
banned_email_file=/etc/vsftpd/banned_emails #禁止使用的匿名用户登陆时作为密码的电子邮件地址
xferlog_file=/var/log/vsftpd.log #日志文件位置
message_file=.message #目录信息文件
user_config_dir=/etc/vsftpd/userconf  #定义用户配置文件的目录
local_root=webdisk #此项设置每个用户登陆后其根目录为/home/username/webdisk。定义本地用户登陆的根目录,注意定义根目录可以是相对路径也可以是绝对路径。相对路径是针对用户家目录来说的.
anon_root=/var/ftp   #匿名用户登陆后的根目录

显示欢迎信息

1
2
3
4
ftpd_banner=welcome to FTP .  #login时显示欢迎信息.如果设置了banner_file则此设置无效
dirmessage_enable=YES   #允许为目录配置显示信息,显示每个目录下面的message_file文件的内容
在设置了这个属性之后,只要在每一个文件夹下面创建一个以message_file定义的文件为名的文本文件(默认是.message),那么在打开到这个文件夹时就会显示该文件中的欢迎信息。
setproctitle_enable=YES   #显示会话状态信息,关!

ubuntu中apt-get的卸载参数

Posted on 2015-10-21 | In Linux

很多情况下,当我们遇到一些软件出错的时候,我们正常会选择重新安装软件来初始化我们的配置文件,然而事实上,仅仅调用普通的apt-get remove 命令是不能完全重新安装软件的。
很多配置文件的信息,和一些错误的配置都会保留下来,导致尽管重新安装软件仍然会出现与之前相同的错误或者配置文件并没有真正初始化。
这时候其实只要在之前的命令后面多加一个–purge参数就能够做到清理残余文件的作用。
比如之前配置vsftpd的时候,好像由于乱改了什么东西,导致出现服务无法正常启动的错误,使用

1
2
myths@myths-X450LD:~$ sudo service vsftpd stop```
命令时会报

stop: Unknown instance:

1
当时病急乱投医,搜索了好久关于service stop命令的东西,结果始终解决不了,软件卸了装装了卸还是没有什么用,走了许多的弯路。后来才发现其实只要在卸载的时候加上这个参数再重新安装软件即可:

myths@myths-X450LD:~$ sudo apt-get remove –purge vsftpd

这个命令虽然十分简单,但是绝对实用,以后遇到类似的问题时用这个东西应该就可以迎刃而解了。

vsftp服务的搭建和配置(1/2)

Posted on 2015-10-20 | In Linux

简述

vsftpd,又叫Very Secure FTP daemon,是一种Linux下安全的文件传输软件。安装和配置也很简单,平时传传文件也是非常有用的。

安装和启动

1
root@iZ28ntr2ej5Z:~# apt-get install vsftpd

即可安装完成。

1
root@iZ28ntr2ej5Z:/# service vsftpd start

即可启动服务。

1
root@iZ28ntr2ej5Z:/# service vsftpd stop

即可停止服务。

1
root@iZ28ntr2ej5Z:/# service vsftpd restart

即可重启服务。
有时候stop命令会出现错误,虽然不知道是怎么回事,但是重新安装一下就可以了。当然这里有个坑。。

用户管理

Vsftpd的用户有三种形式:

  1. 匿名用户形式:在默认安装的情况下,系统只提供匿名用户访问
  2. 本地用户形式:以/etc/passwd中的用户名为认证方式
  3. 虚拟用户形式:支持将用户名和口令保存在数据库文件或数据库服务器中。相对于FTP的本地用户形式来说,虚拟用户只是FTP服务器的专有用户,虚拟用 户只能访问FTP服务器所提供的资源,这大大增强系统本身的安全性。相对于匿名用户而言,虚拟用户需要用户名和密码才能获取FTP服务器中的文件,增加了 对用户和下载的可管理性。对于需要提供下载服务,但又不希望所有人都可以匿名下载;既需要对下载用户进行管理,又考虑到主机安全和管理方便的FTP站点来 说,虚拟用户是一种极好的解决方案。

配置文件

主配置文件为:/etc/vsftpd.conf

我本机的配置文件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# Example config file /etc/vsftpd.conf
#
# The default compiled in settings are fairly paranoid. This sample file
# loosens things up a bit, to make the ftp daemon more usable.
# Please see vsftpd.conf.5 for all compiled in defaults.
#
# READ THIS: This example file is NOT an exhaustive list of vsftpd options.
# Please read the vsftpd.conf.5 manual page to get a full idea of vsftpd's
# capabilities.
#
#
# Run standalone? vsftpd can run either from an inetd or as a standalone
# daemon started from an initscript.
listen=YES
#
# Run standalone with IPv6?
# Like the listen parameter, except vsftpd will listen on an IPv6 socket
# instead of an IPv4 one. This parameter and the listen parameter are mutually
# exclusive.
#listen_ipv6=YES
#
# Allow anonymous FTP? (Disabled by default)
anonymous_enable=YES
# Uncomment this to allow local users to log in.
local_enable=YES
#
# Uncomment this to enable any form of FTP write command.
#write_enable=YES
#
# Default umask for local users is 077\. You may wish to change this to 022,
# if your users expect that (022 is used by most other ftpd's)
#local_umask=022
#
# Uncomment this to allow the anonymous FTP user to upload files. This only
# has an effect if the above global write enable is activated. Also, you will
# obviously need to create a directory writable by the FTP user.
#anon_upload_enable=YES
#
# Uncomment this if you want the anonymous FTP user to be able to create
# new directories.
#anon_mkdir_write_enable=YES
#
# Activate directory messages - messages given to remote users when they
# go into a certain directory.
dirmessage_enable=YES
#
# If enabled, vsftpd will display directory listings with the time
# in your local time zone. The default is to display GMT. The
# times returned by the MDTM FTP command are also affected by this
# option.
use_localtime=YES
#
# Activate logging of uploads/downloads.
xferlog_enable=YES
#
# Make sure PORT transfer connections originate from port 20 (ftp-data).
connect_from_port_20=YES
#
# If you want, you can arrange for uploaded anonymous files to be owned by
# a different user. Note! Using "root" for uploaded files is not
# recommended!
#chown_uploads=YES
#chown_username=whoever
#
# You may override where the log file goes if you like. The default is shown
# below.
#xferlog_file=/var/log/vsftpd.log
#
# If you want, you can have your log file in standard ftpd xferlog format.
# Note that the default log file location is /var/log/xferlog in this case.
#xferlog_std_format=YES
#
# You may change the default value for timing out an idle session.
#idle_session_timeout=600
#
# You may change the default value for timing out a data connection.
#data_connection_timeout=120
#
# It is recommended that you define on your system a unique user which the
# ftp server can use as a totally isolated and unprivileged user.
#nopriv_user=ftpsecure
#
# Enable this and the server will recognise asynchronous ABOR requests. Not
# recommended for security (the code is non-trivial). Not enabling it,
# however, may confuse older FTP clients.
#async_abor_enable=YES
#
# By default the server will pretend to allow ASCII mode but in fact ignore
# the request. Turn on the below options to have the server actually do ASCII
# mangling on files when in ASCII mode.
# Beware that on some FTP servers, ASCII support allows a denial of service
# attack (DoS) via the command "SIZE /big/file" in ASCII mode. vsftpd
# predicted this attack and has always been safe, reporting the size of the
# raw file.
# ASCII mangling is a horrible feature of the protocol.
#ascii_upload_enable=YES
#ascii_download_enable=YES
#
# You may fully customise the login banner string:
#ftpd_banner=Welcome to blah FTP service.
#
# You may specify a file of disallowed anonymous e-mail addresses. Apparently
# useful for combatting certain DoS attacks.
#deny_email_enable=YES
# (default follows)
#banned_email_file=/etc/vsftpd.banned_emails
#
# You may restrict local users to their home directories. See the FAQ for
# the possible risks in this before using chroot_local_user or
# chroot_list_enable below.
#chroot_local_user=YES
#
# You may specify an explicit list of local users to chroot() to their home
# directory. If chroot_local_user is YES, then this list becomes a list of
# users to NOT chroot().
# (Warning! chroot'ing can be very dangerous. If using chroot, make sure that
# the user does not have write access to the top level directory within the
# chroot)
#chroot_local_user=YES
#chroot_list_enable=YES
# (default follows)
#chroot_list_file=/etc/vsftpd.chroot_list
#
# You may activate the "-R" option to the builtin ls. This is disabled by
# default to avoid remote users being able to cause excessive I/O on large
# sites. However, some broken FTP clients such as "ncftp" and "mirror" assume
# the presence of the "-R" option, so there is a strong case for enabling it.
#ls_recurse_enable=YES
#
# Customization
#
# Some of vsftpd's settings don't fit the filesystem layout by
# default.
#
# This option should be the name of a directory which is empty. Also, the
# directory should not be writable by the ftp user. This directory is used
# as a secure chroot() jail at times vsftpd does not require filesystem
# access.
secure_chroot_dir=/var/run/vsftpd/empty
#
# This string is the name of the PAM service vsftpd will use.
pam_service_name=vsftpd
#
# This option specifies the location of the RSA certificate to use for SSL
# encrypted connections.
rsa_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
# This option specifies the location of the RSA key to use for SSL
# encrypted connections.
rsa_private_key_file=/etc/ssl/private/ssl-cert-snakeoil.key

以上是我本机的/etc/vsftpd.conf的初始配置,至于一些配置细节下次在详细说明。

概率dp专题整理(2/2)

Posted on 2015-10-17 | In Algorithm

LightOJ 1027 A Dangerous Maze:

预先求出递推式,最后通过公式直接计算。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std;
int gcd(int a, int b){
if (b == 0)
return a;
return gcd(b, a%b);
}
int main(){
int T;
scanf("%d", &T);
for (int t = 1; t <= T; t++){
int n;
scanf("%d", &n);
int p = 0, q = n,num;
for (int i = 1; i <= n; i++){
scanf("%d", &num);
if (num < 0){
q--;
p -= num;
}
else{
p += num;
}
}
if (q == 0){
printf("Case %d: infn",t);
}
else{
int div = gcd(p, q);
printf("Case %d: %d/%dn",t,p/div,q/div);
}
}
}

LightOJ 1284 Lights inside 3D Grid:

要判断经过k次变换后的开灯的数目,我们可以先计算对于每一个cell而言,在经历了k次变换后,仍然开灯的期望,最后将每一个cell的期望相加即可。

有一个M*N*P的立方体,每次随机选两个格子,把它们之间的灯全打开(如果已经是打开的就关闭),经过K次操作之后开着的灯的个数的期望是多少。

把每个灯经过K次操作亮着的概率P求出来,因为每个灯是独立的,最后的期望也就是:
$$\Sigma(Pi*1+(1-Pi)*0)$$

对于一个灯来说, 设f[i]是经过i次操作亮着的概率,g[i]是经过i次操作不亮的概率,则有$f[i]+p[i]=1,f[i]=f[i-1]*(1-p)+g[i-1]*p$,这里的p是操作一次能操作到这个灯的概率。

通过这两个式子,能得到$f[i]=f[i-1]*(1-2p)+p$,两边加上b/(a-1),也就是0.5,成为等比数列,最后得到$f[i]=0.5-0.5*(1-2p)^i$。

那么只要对每个灯求出p就能算出答案了。能操作到这个灯等价于选的两个点的坐标在x轴,y轴,z轴都分别在这个灯坐标的两侧,对每个轴分别算符合的情况,然后相乘,最后除以所有情况就是概率。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <cstdio>
#include <cmath>

double Get (int a,int b)
{
return 1.0*b*b-(a-1)*(a-1)-(b-a)*(b-a);
}

int main ()
{
int T;
scanf("%d",&T);
for (int Cas=1;Cas<=T;Cas++)
{
int x,y,z,n;
scanf("%d%d%d%d",&x,&y,&z,&n);
double ans=0,p,t=1.0*x*x*y*y*z*z;
for (int i=1;i<=x;i++)
for (int j=1;j<=y;j++)
for (int k=1;k<=z;k++)
{
p=1.0*Get(i,x)*Get(j,y)*Get(k,z)/t;
ans+=0.5-0.5*pow(1-2*p,1.0*n);
}
printf("Case %d: %lfn",Cas,ans);
}
return 0;
}

数论基础专题小结

Posted on 2015-10-14 | In Algorithm

这个专题很杂,牵涉到很多数学公式和一些优化方法,还是要根据不同的题目来积累经验。


LightOJ 1282 Leading and Trailing:
这道题牵涉到求一个大数的前几位和后几位的方法,前者主要是通过对数进行处理,后者通过快速取模。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std;
int powMod(int a,int n,int mod){
int ans=1;
while(n>0){
if(n&1){
ans=ans*a%mod;
}
n>>=1;
a=a*a%mod;
}
return ans;
}
int getHead(int n,int k){
return pow(10,2+fmod(k*log10(n),1));
}
int main(){
int t;
scanf("%d",&t);
for(int i=1;i<=t;i++){
int n,k;
scanf("%d%d",&n,&k);

printf("Case %d: %d %03dn",i,getHead(n,k),powMod(n%1000,k,1000));
}
}

[LightOJ 1259 Goldbach`s Conjecture:](http://acm.hust.edu.cn/vjudge/contest/view.action?cid=70017#problem/F)

这道题主要是判断素数和素数表相结合,用素数表提高枚举效率,通过 判断素数表 提高判断的效率。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std;
vector<int>prime;
bool p[10000004];
int main(){
    int tt;
    prime.clear();
    memset(p,0,sizeof p);
    for(int i=2;i<=10000000;i++){
        if(p[i]==0){
            prime.push_back(i);
            for(int j=2;i*j<=10000000;j++){
                p[j*i]=1;
            }
        }
    }
    scanf("%d",&tt);
    for(int t=1;t<=tt;t++){
        int n;
        scanf("%d",&n);
        int ans=0;
        for(int i=0;prime[i]*2<=n;i++){
            if(p[n-prime[i]]==0){
                ans++;
            }
        }
        printf("Case %d: %dn",t,ans);
    }
}```

概率dp专题整理(1/2)

Posted on 2015-10-13 | In Algorithm

概率DP主要用于求解期望、概率等题目。转移方程有时候比较灵活,没有固定的范式,没有模版可言。正如大部分的dp题目一样,思考量远大于代码量。需要注意的是,一般求概率是正推,求期望是逆推。


LightOJ 1030 Discovering Gold:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
int a[104];
double dp[104];
int main(){
int tt;
scanf("%d", &tt);
for (int t = 1; t <= tt; t++){
int n;
memset(dp, 0, sizeof dp);
scanf("%d", &n);
for (int i = 1; i <= n; i++){
scanf("%d", &a[i]);
}
dp[n] = a[n];
for (int i = n-1; i >= 1; i--){
int cnt = 0;
for (int j = 1; j <= 6; j++){
if (i + j > n){
break;
}
else{
cnt++;
}
dp[i] += dp[i+j];
}
dp[i] =dp[i]/cnt+a[i];
}
printf("Case %d: %fn", t, dp[1]);
}
}

LightOJ 1104 Birthday Paradox:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
int main(){
int t;
scanf("%d", &t);
for (int i = 1; i <= t; i++){
int n;
scanf("%d", &n);
double ans = 1.0;
int k = 0;
while (ans * 2 > 1){
k++;
ans = ans*(n - k) / n ;
}
printf("Case %d: %dn",i, k);
}
}

LightOJ 1248 Dice (III):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
int main(){
int t;
scanf("%d", &t);
for (int tt = 1; tt <= t; tt++){
int n;
scanf("%d", &n);
double ans = 0;
for (int i = 1; i <= n; i++){
ans += 1.0*n / i;
}
printf("Case %d: %fn", tt,ans);

}
}

LightOJ 1265 Island of Survival:

1
2
3
4
5
6
7
8
9
10
11
12
13
#include<cstdio>
double fun(int n){
return n == 0 ? 1 : fun(n - 2)*(n - 1) / (n + 1);
}
int main(){
int tt;
scanf("%d", &tt);
for (int t = 1; t <= tt; t++){
int a, b;
scanf("%d%d", &a, &b);
printf("Case %d: %.7lfn", t, a & 1 ? 0 : fun(a));
}
}

LightOJ 1038 Race to 1 Again:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
double dp[100004];
double dfs(int n){
if (fabs(dp[n] + 1) > 0.0000001)
return dp[n];
double ans = 0;
int i, cnt = 2;
for (i = 2; i*i < n; i++){
if (n%i == 0){
ans += dfs(i);
ans += dfs(n / i);
cnt += 2;
}
}
if (i*i == n){
ans += dfs(i);
cnt++;
}
return dp[n] =( ans + cnt) / (cnt - 1);
}
int main(){
int tt;
scanf("%d", &tt);
for (int i = 1; i <= 100000; i++){
dp[i] = -1;
}
dp[1] = 0;
for (int t = 1; t <= tt; t++){
int n;
scanf("%d", &n);
printf("Case %d: %.7lfn", t, dfs(n));
}
}

LightOJ 1079 Just another Robbery:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
double dp[10004];
double risk[104];
int money[104];
int main(){
int tt;
scanf("%d", &tt);
for (int t = 1; t <= tt; t++){
memset(risk, 0, sizeof risk);
memset(money, 0, sizeof money);
double p;
int n;
scanf("%lf%d", &p, &n);
for (int i = 1; i <= n; i++){
scanf("%d%lf", &money[i], &risk[i]);
}
for (int i = 0; i <= 10000; i++)
dp[i] = 1;
dp[0] = 0;
for (int i = 1; i <= n; i++){
for (int j = 10000; j >= 0; j--){
if (j >= money[i]){
dp[j] = min(dp[j], 1 - (1 - dp[j - money[i]])*(1 - risk[i]));
}
}
}
int ans = 0;
for (int i = 1; i <= 10000; i++){
if (dp[i] <= p){
ans = max(ans, i);
}
}
printf("Case %d: %dn", t, ans);
}
}

区间dp专题小结

Posted on 2015-10-12 | In Algorithm

区间DP是一类在区间上进行动态规划的最优问题,一般是根据问题设出一个表示状态的dp,可以是二维的也可以是三维的,一般情况下为二维。然后将问题划分成两个子问题,也就是一段区间分成左右两个区间,然后将左右两个区间合并到整个区间,或者说局部最优解合并为全局最优解,然后得解。
这类DP可以用常规的for循环来写,也可以用记忆化搜索来写。一般情况下记忆化搜索的代码比较好写,所以一般都用dfs来代替获得dp值。然而说到底,这只是一种思想,具体的代码根据题目的不同差别很大,而且有很多需要考虑的细节。


POJ-1651-Multiplication-Puzzle:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int a[104], dp[104][104];
int dfs(int x, int y){
if (dp[x][y] != -1)
return dp[x][y];
if (x + 1 >= y)
return dp[x][y]=0;
dp[x][y] = 0x7fffff;
for (int i = x + 1; i < y; i++){
dp[x][y] = min(dp[x][y], dfs(x, i) + dfs(i, y) + a[x] * a[i] * a[y]);
}
return dp[x][y];
}
int main(){
int n;
while (scanf("%d", &n) == 1){
memset(a, 0, sizeof a);
memset(dp, -1, sizeof dp);
for (int i = 1; i <= n; i++){
scanf("%d", &a[i]);
}
printf("%dn", dfs(1, n));
}
}

POJ-2955-Brackets:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
char s[104];
int dp[104][104];
bool match(char a, char b){
return a == '('&&b == ')' || a == '['&&b == ']';
}
int dfs(int x, int y){
if (dp[x][y] != -1)
return dp[x][y];
if (x + 1 >= y)
return dp[x][y] = 0;
dp[x][y] = 0;
for (int i = x; i < y; i++){
for (int j = i + 1; j < y; j++){
if (match(s[i], s[j])){
dp[x][y] = max(dp[x][y], dfs(i + 1, j) + 1 + dfs(j + 1,y));
}
}

}
return dp[x][y];
}

int main(){
while (true){
memset(dp, -1, sizeof dp);
gets(s);
if (strcmp(s, "end") == 0)
break;
printf("%dn", 2 * dfs(0, strlen(s)));
}
}
1…545556…58

574 posts
69 categories
286 tags
© 2024 Companyd
Powered by Hexo
|
Theme — NexT.Muse v5.1.4