C#: 删除文本段落中的不可见字符

很简单的一个程序

只包含删除文本换行符,或者其他不可见字符.同时可以设置在删除特殊字符之后将替换后的结果设置到剪贴板.

image-2890

程序运行截图

image-2891

源码

完整源码在: Gitee仓库

public static string DeleteUnVisibleChar(string sourceString)
{
    System.Text.StringBuilder sBuilder = new System.Text.StringBuilder(131);
    for (int i = 0; i < sourceString.Length; i++)
    {
        int Unicode = sourceString[i];
        if (Unicode >= 16)
        {
            sBuilder.Append(sourceString[i].ToString());
        }
    }
    return sBuilder.ToString();
}

完整源码在: Gitee仓库

C#: 抽奖程序

抽奖程序

只是一个简单的抽奖程序,可以添加人员,可以手动抽奖(但还没有抽奖概率设置).

程序截图

image-2885

源码

image-2886

完整源码地址: Gitee仓库

这个是最终显示中奖人的方法,需要添加中奖概率,可以在这里面添加:

MainForm.cs:

private void StopTimer_Click(object sender, EventArgs e)
{
    if (timer1.Enabled)
    {
        timer1.Stop();
        StartTimer.Enabled = true;
        StopTimer.Enabled = false;
        MessageBox.Show("恭喜 " + nameShowBox.Text.ToString() + "获奖!");
        personListSettings.Remove(nameShowBox.Text.ToString()); // 删掉这一项.
        personCountBox.Text = personListSettings.Count + " 人";
        surpriseList.Items.Add(nameShowBox.Text.ToString());
        nameShowBox.Text = "下一个幸运儿";
        if (personListSettings.Count == 2)
        {
            MessageBox.Show("可参加中奖人数只有2人,请先添加人员!");
            StartTimer.Enabled = false;
            StopTimer.Enabled = false;
        }
    }
}

完整源码地址: Gitee仓库

C# : 异步更新UI

源于

提示:该程序为C#的Winform程序,可在Windows上直接运行.

之前写了一个Winform程序,需要异步更新UI(例如,在Android中,是明确禁止同步更新UI的.).于是请教了一些网友,得出下面的程序.

其实原理都比较简单,就是把网络请求放到另外一个线程里面去执行.等网络请求线程执行完成之后,通过回调或其他方式执行UI线程更新.

image-2857

运行截图

程序运行截图如下,图示为已经加载完成数据的效果:

image-2858

源码

完整源码在: Gitee仓库

请求的网络地址为: http://www.weather.com.cn/data/sk/101270101.html,有时候网络会比较慢..

发送请求封装部分:

// allDone 属性包含 ManualResetEvent 类的实例,它指示请求完成。
        public ManualResetEvent allDone = new ManualResetEvent(false);

        // 它创建 WebRequest wreq 和 RequestState rs,调用 BeginGetResponse 开始处理请求,然后调用 allDone.WaitOne() 方法,
        // 以便应用程序不会在回调完成前退出。 在从 Internet 资源读取响应后,Main() 将该响应写入到控制台,应用程序结束。
        public void SendGet(string url,  HttpResultGet resultGet, FormInterface formTransInterface, WebHeaderCollection whcl = null)
        {
            try
            {
                WebRequest wreq = WebRequest.Create(url);
                if (whcl != null)
                {
                    ((HttpWebRequest)wreq).Headers = whcl;
                }
                // Create the state object.  
                ASyncRequestState rs = new ASyncRequestState
                {
                    // Put the request into the state object so it can be passed around.  
                    Request = wreq
                };

                // Issue the async request.  
                IAsyncResult r = wreq.BeginGetResponse(
                   new AsyncCallback(RespCallback), rs);

                // Wait until the ManualResetEvent is set so that the application   
                // does not exit until after the callback is called.  
                allDone.WaitOne();
                if (rs.RequestData.ToString().Length > 0)
                {
                    resultGet.ResultSet(rs.RequestData.ToString(), formTransInterface);
                }
            }
            catch (WebException)
            {
                resultGet.ResultSet("[请求错误]网络请求发生未知错误,请稍候重试!", formTransInterface);
            }
            catch (Exception)
            {
                resultGet.ResultSet("[请求错误]网络请求发生未知错误,请稍候重试!", formTransInterface);
            }

        }

异步回调封装部分:

// RespCallBack() 方法实现 Internet 请求的异步回调方法。 
        // 该方法创建包含来自 Internet 资源的响应的 WebResponse 实例,
        // 获取响应流,然后开始从该流异步读取数据。
        private void RespCallback(IAsyncResult ar)
        {
            // Get the ASyncRequestState object from the async result.  
            ASyncRequestState rs = (ASyncRequestState)ar.AsyncState;

            // Get the WebRequest from AsyncRequestState.  
            WebRequest req = rs.Request;

            // Call EndGetResponse, which produces the WebResponse object  
            //  that came from the request issued above.  
            WebResponse resp = req.EndGetResponse(ar);

            //  Start reading data from the response stream.  
            Stream ResponseStream = resp.GetResponseStream();

            // Store the response stream in AsyncRequestState to read   
            // the stream asynchronously.  
            rs.ResponseStream = ResponseStream;

            // Open the stream using a StreamReader for easy access.  
            StreamReader reader = new StreamReader(ResponseStream);
            // Read the content.  
            string responseFromServer = reader.ReadToEnd();

            rs.RequestData.Append(
                   responseFromServer);

            // Close down the response stream.  
            reader.Close();
            // Set the ManualResetEvent so the main thread can exit.  
            allDone.Set();
        }

代码调用:

        /**
         * 发送异步网络请求.
         *
         *
         */
        public void SendGet(string url, FormInterface formInterface)
        {

            // 随便显示的一个天气地址.
            AsyncHttpUtil asyncHttpUtil = new AsyncHttpUtil();
            asyncHttpUtil.SendGet(url, new SendHTTP(), formInterface);
        }

        // 异步回调
        void HttpResultGet.ResultSet(string result, FormInterface formInterface)
        {
            formInterface.SendResult(result);
        }

程序入口调用:

/**
         * 接收异步返回结果.
         * 
         */
        void FormInterface.SendResult(string text)
        {
            MessageBox.Show(text);
            this.targetText.Text = text;
        }
        /**
         * 模拟发送异步请求.
         *    
         */
        private void send_Click(object sender, EventArgs e)
        {
            SendHTTP send = new SendHTTP();
            send.SendGet("http://www.weather.com.cn/data/sk/101270101.html", this);
        }

完整源码在: Gitee仓库

C++:简单计算器与排序

两个小程序

包含两个小程序,一个对数字进行计算的(也可以对其他可用类型),第二个是排序的.

C++.
image-2210

计算的小程序


// Example program
#include
#include
#include
using namespace std;

//加减乘除运算.

int main()
{
/*
template struct plus {
T operator() (const T& x, const T& y) const {return x+y;}
typedef T first_argument_type;
typedef T second_argument_type;
typedef T result_type;
};

例如:上面是plus的原型,可以看出其中重载了加法运算.(其他的类似)
更多可以参考:http://www.cplusplus.com/reference/functional/plus/ [应查看c++ 11的示例]
*/
plus age;
minus gre;
multiplies nums;
divides ds;
negate ne;
modulus modu;
///////////////////////////////
cout << "add:" << age(10,20) << endl; cout << "minus:" << gre(100,50) << endl; cout << "mulitplies:" << nums(50,100) << endl; cout << "divides:" << ds(100,2) << endl; cout << "negate:" << ne(100) << endl; cout << "modulus:" << modu(100,10) << endl; return 0; }

逆序排序

下面的程序其实使用了上面程序中的匿名negate对象(negate会倒置传入的值).

negate原型如下:


template struct negate {
T operator() (const T& x) const {return -x;}
typedef T argument_type;
typedef T result_type;
};
//更多可参考:http://www.cplusplus.com/reference/functional/negate/

程序如下:

// Example program
#include
#include
#include
#include
using namespace std;

//逆序排列vector中的元素

int main()
{
vector vec={5,20,70,6,100,658,50,3,1558,1,85217,0};
sort(vec.begin(),vec.end(),greater());
for_each(vec.begin(),vec.end(),[](const int &is){cout << is << " " ;}); cout << endl; return 0; }

C++:可调用对象与function

一点东西

题目也可以是函数表(用于存储指向可调用对象的”指针”).


//普通函数
int add(int i,int j){ return i+j; }
//lambda,其产生一个未命名的函数对象类.
auto mod = [](const int &i,const int &j){ return i+j; }
//函数对象类.
struct divide{
int operator()(int denominator,int divisor)
{
return denominator / divisor;
}
};

上面这些可调用对象,虽然类型不同,但是共享同一种调用形式:

int(int,int)

可以定义一个函数表,用于存储指向这些可调用对象的”指针”.当程序需要执行某个特定的操作时,
从表中查找该调用的函数.

在C++中,函数表很容易通过map来实现.

简单意思就是将与int(int,int)一样的类型,放入一个map中,将其的操作作为map的主键.

形如:

map["+"]=add;//add是一个函数指针.
map["-"]=minus;//同add的含义一样.
map["*"]=..
以此类推..

C++.
image-2208

代码实现

下面的代码可以运行,推荐一个在线运行的网址:CPP.SH


// Example program
#include
#include
#include

#include
using namespace std;

/*
//普通函数
int add(int i,int j){ return i+j; }
//lambda,其产生一个未命名的函数对象类.
auto mod = [](const int &i,const int &j){ return i+j; }
//函数对象类.
struct divide{
int operator()(int denominator,int divisor)
{
return denominator / divisor;
}
};

上面这些可调用对象,虽然类型不同,但是共享同一种调用形式:
int(int,int)

可以定义一个函数表,用于存储指向这些可调用对象的"指针".当程序需要执行某个特定的操作时,
从表中查找该调用的函数.

在C++中,函数表很容易通过map来实现.

*/
int add(int i,int j){
return i+j;
}

struct divide{
int operator()(int denominator,int divisor)
{
return denominator / divisor;
}
};

int main()
{
auto mod = [](const int &i,const int &j){ return i+j; };
map binops;
binops.insert({"+",add});
//但是我们不能将mod或者divide存入binops.因为mod不是一个函数指针.
//问题在于mod是个lambda表达式,而每个lambda有它自己的类类型,该类型与存储在binops中的值得类型不匹配.

//解决办法如下:
//使用一个名为function的新的标准库类型解决上述问题.

/*function f1 = add;//函数指针
function f2 = divide();//函数对象类的对象.
function f3 = [](int i,int j){ return i * j ; }; //lambda

cout << f1(4,2) << endl; cout << f2(4,2) << endl; cout << f3(4,2) << endl;*/ //使用function类型我们可以重新定义map. map> binops2={
{"+",add}, //函数指针.
{"-",std::minus()}, //标准库函数对象
{"/",divide()}, //用户定义的函数对象.
{"*",[](int i,int j){ return i * j ;}}, //未命名的lambda
{"%",mod} //命名了的lambda对象
};

cout << "10+5=" << binops2["+"](10,5) << endl;//调用add(10,5) cout << "10-5=" << binops2["-"](10,5) << endl;//调用minus
cout << "10/5=" << binops2["/"](10,5) << endl;//调用divide cout << "10*5=" << binops2["*"](10,5) << endl;//调用lambda cout << "10%5=" << binops2["%"](10,5) << endl;//调用lambda /* 我们不能(直接)将重载函数的名字存入function类型的对象中: int add(int i,int j){return i+j;} Sales_data add(const Sales_data&,const Sales_data&); map> binops3;
binops3.insert({"+",add}); //错误:哪个add?

解决上述二义性的问题是存储函数指针而非函数的名字:

int (*fp)(int,int) =add; //指针所指的add是接受两个int的版本.
binops3.insert({"+",fp}); //正确:fp指向一个正确的add版本

同样,也可以用lambda来消除二义性:

//正确:使用lambda来指定我们希望使用的add版本
binops3.insert({"+",[](int a,int b){return add(a,b);}});

*/

return 0;
}