2018年2月6日 星期二

visual studio 插入片段代碼 快速打出重複文字

visual studio 插入片段代碼 快速打出重複文字

用過 sublimetext 一直很喜歡他的插入片段 snippet,後來需要開發比較大的專案 sublimetext 就顯得有點功能不足了,改用了VS,一開始很不習慣缺了很多片段插入,後來才發現其實VS也可以自訂

安裝套件


先到這裡來打開更新管理員

再來搜尋 snippet desingner 安裝他

使用

使用上很簡單,不過一開始可能會搞不清楚狀況

直接對著你需要插入的代碼框起來按右鍵,就可以新增了,儲存的時候不要改位置直接存檔。

這個是已經做好的片段,可以看一下這邊意思
$void$ $function_name$($int$ $var$){
    $end$
    $return$;
}

上方

A:snippet→ 你在片段管理員會看到的名稱可以詳細打全名,但是也不要太長
B:shortcut→ 你在打程式中呼叫的代號
這邊的定義就是在代碼中打B會看到一個片段是B,B的詳細說明是A

中間片段

中間手動打之後會自動跑到下面,大致上來說就兩個用法
$str$ 直接打你要的字符,str是預設出現的東西會框起來給你改
打出第二個以上會要讓你用 tab 選擇。
使用時會一直在亮起來的地方輪流
$end$ 結束的時候要在哪裡,結束的意思是指按enter,如果一直按 tab 就是前面的代碼一直輪流跑,直到在任一次循環按下enter直接跳到結尾。(預設的for迴圈也是這樣的可以玩玩看功能)
當你按下 enter 之後就跑來這裡
這裡還有一個用法是 $selected$ 不過我也用不出來是要幹嘛,參考內建的用法他好像通常都出現在 $end$ 之前,但是實測就算拿掉 $selected$ 功能也不會有影響。

其他

在一個選項 kind(種類) 中有一個 object 與 literal 可選,我有去查一下好像是插 object 可以從外部輸入,但是具體我也不曉得怎麼用。
在不從外部插入的情況下,使用上兩者沒有任何區別;沒特別需求的人可以當作一樣的好。

其他方便的片段

快速打出 cout
cout << "$string$=" << $var$ << endl;
$selected$ $end$
初始化main函式
#include <iostream>
using namespace std;

//====================================================================================
int main(int argc, char const *argv[]){
    $end$
    return 0;
}
//====================================================================================

2018年2月5日 星期一

Windwos 網路共享印表機 批次檔 自動連結印表機

Windwos 網路共享印表機 批次檔 自動連結印表機

連接的時候遇到幾個問題
  1. 沒有記住帳號開啟 pdf word 會卡很久沒有回應
  2. 共享資料夾管理員權限

沒有記住帳號

發生的原因是沒有記住登入帳號,導致重新開機之後就沒有權限可以存取印表機了,但是印表機還連接著,這時候如果開 PDF 或是 WORD 這種印列功能的軟體就會當掉,卡住等個幾分鐘才會正常。
只能記住帳號保持電腦一直有權限讀取印表機了沒有找到什麼解決方法。或者如果環境允許直接把那台電腦設成共享不用密碼,也可以避免這個問題。

共享資夾權限

遇到的時候覺得蠻奇怪,後來摸清楚了才知道這樣做比較合理,排除帳密權限問題假如現在有三台電腦,以及一個帶有盾牌的 .exe 也就是打開時會詢問你是否使用管理員權限的檔案。
  • 台電腦A開啟免密碼的可讀寫共用
  • 我用電腦B放置執行檔,在電腦B執行正常有管理員權限。
  • 我用電腦C讀取B所放置的執行檔,會沒有管理員權限導致執行失敗。
反過來也是一樣的情況,我一開始的規劃是電腦A開印表機共享+驅動資料夾共享,然後再驅動資料夾放置一個執行檔帶有管理員權限會自動連接印表機+裝驅動,後來測試一下用別的電腦都會失敗才發現這個規則;要放的話可能就是使用自己要copy到桌面再啟動。

批次檔的指令

最後放上鏈接的批次檔指令,分兩個部分
@Echo Off
Title AddPath - By:Charlotte.HonG
:: Date :2017/11/29
:: Final :2017/11/29
::===========================================================
::確認是否為管理員權限
call :IsAdmin
::===========================================================
::安裝裝驅動
pnputil -a \\192.168.1.1\Brother_DCP-7040_Driver\BRPRMA7A.inf
::連接印表機
rundll32 printui.dll,PrintUIEntry /in /n \\192.168.1.1\dcp7040
::===========================================================
Exit

:IsAdmin
@Echo Off
Reg.exe query "HKU\S-1-5-19\Environment"
If Not %ERRORLEVEL% EQU 0 (
  Cls
  Echo [權限不足] 需使用管理員權限開啟
  Pause & Exit
)
goto:eof
備註:BRPRMA7A.inf 這個檔案在驅動裡面有多份 inf 要看一下到底是哪個。
檔案內容長的像這樣,有明確表示說哪一個驅動用哪一段,這個應該可以協助判別正確是哪個檔案。

安裝驅動

這部分是安裝之後在連接的時候就不用在自動指定驅動位置,雖說是安裝不過用複製驅動到Win裡面,可能比較貼切。
這裡節省的動作就是會自動找驅動而不用手動選位置。

連接目標印表機

就是你到網路上的芳鄰按右鍵連線的意思
這裡節省的動作就是還要去開網路上的芳鄰打ip。
不曉得怎麼把指令串起來,這個命令執行之後就是出現安裝精靈,然後一直按下一步就好了。期望的目標結果是執行之後自動連好,不希望有什麼畫面還要按下一步
指令測試了好久還是失敗就放棄了~如果有人知道的希望可以留言告訴我

2018年1月30日 星期二

C++ boost lib 如何安裝在 Visual Stusio 2017 15.5 版

C++ boost lib 如何安裝在 Visual Stusio 2017 15.5 版

下載

先下載這些下來
boost官方載點:Boost Downloads

編譯

批次檔要整個github都下載下來,再來把 boost_1_66_0.zip 解開直接丟進去批次檔裡面,然後執行批次檔 build_boost_1_66_vs2017.5,要跑一段時間就編譯完成了。

使用

解之後開進去 boost1_66_0 會多一個 stage 裡面就是編譯好的 lib 檔案,就可以直接拿來用了。
include的目錄就是那一整個 boost 裡面都是很雜很多。
這一篇是設定別的函式庫,就是把 lib 跟 include 的目錄改掉而已,而bin目錄不需要設置。

測試代碼

#include <iostream>
using namespace std;

#include <boost/thread/thread.hpp>
#include <boost/bind.hpp> 
using namespace boost;

#include <boost/multiprecision/cpp_int.hpp>
using namespace boost::multiprecision;

void helloworld() {
    cout << "Hello World!" << endl;
}

int main(int argc, char const *argv[]) {
    thread thrd(&helloworld);
    thrd.join();

    uint1024_t bigNum = -1;
    cout << bigNum << endl;
    return 0;
}

參考

2018年1月29日 星期一

C/C++ 字串接字串或int 範例

C/C++ 字串接字串或int 範例

如何把 int 轉成字串可以參考站內文:
C and C++ 字串(string) 轉 數字,數字 轉 字串(string) 綜合整理
/*****************************************************************
Name : string append
Date : 2018/01/29
By   : CharlotteHonG
Final: 2018/01/29
*****************************************************************/
#include <iostream>
#include <string>
#include <cstring>
using namespace std;

//================================================================
int main(int argc, char const *argv[]){
    char str[]="ABC\0";

    // c++ style
    int num = 7;
    cout << str << "DEF=\0" << num << endl;
    cout << string(str)+"DEF=\0"+to_string(num) << endl;

    // c style
    char buf[9];
    strcpy(buf, str);
    strcat(buf, "DEF=\0"); 
    char buf2[2];
    sprintf(buf2,"%d", 7);
    strcat(buf, buf2); 
    printf("%s\n", buf);
    return 0;
}
//================================================================

2018年1月28日 星期日

OpenCV3 在 VisualStuio 編譯出現 4996 錯誤

OpenCV3 在 VisualStuio 編譯出現 C4996 錯誤
===
錯誤 C4996 ‘fopen’: This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. vla c:\opencv\include\opencv2\flann\logger.h 66
解決辦法是關閉 C4996 警告,可以使用 #program 關閉不過那樣每一份檔案都打,但是相對也比較保險一點,可以告知後面的人。
#pragma warning(disable: 4996)
比較一勞永逸的辦法就是依據錯誤說明上的信息信息下手,在前置處理上加上該巨集。
注意上面的組態要設定對。
realese本身不會出錯只要改debug就好了,截圖的時候沒注意到。
這個出現的原因是因為使用了不安全的函式所導致,詳細可以搜索一下 scanf() 和 scanf_s() 之類的關鍵字。

2018年1月26日 星期五

C/C++ 指標(*) point 和 參考(&) refrence 差別及相關範例

C/C++ 指標(*) point 和 參考(&) refrence 差別及相關範例

本文所指的指針的指針指的是指標,個人覺得這樣比較好做區別
初學時時常讓人搞不清楚的兩個不同的東西,這邊提供幾個大原則做判斷
指針:可以儲存記憶體位置的型別
參考:就好像別名一樣可以完全等同於所指之物
比較特別的還有一種情況叫做(*\&)指針的參考,這又是什麼呢?

兩個符號的用法

分別是
  • *取址 reference
  • &取值 dereference
他們放在非宣告時的變數的前方,從英文可以看出他們具有相反的關係。
首先最讓人搞不清楚的是為什麼他們在宣告時有不同的關係,那根本就是不一樣意思了。
int* i;
int& a;
你把它當作別的東西來看直接把整串看做是一個型別。
我的意思是你不要這樣看int* i; 而直接是 int* i;
前者表示宣告一個指針容器,後者表示宣告一個別名,跟剛剛的*&完全是兩回事。
由此我也更推薦你使用 int* i; 而不是 int *i;這樣更容易表達。
除非你需要連續宣告,這就真的不得已了int *i, *j; 連續宣告時要個別指定。
回到剛剛的取址與取值簡單來說就是你現在有一個變數,它存在記憶體的某個地方,這個某個地方會用一串數值表示位置比如說 0x01
現在你手上拿到 p=0x01 你希望獲取他的數值就是使用取值 *p 獲取內容
你現在手上拿到 p=0; 你希望獲取他的地址就是使用取址 &p 獲取地址

地址的傳遞可以共同編輯

函式(包含main)內都有各自的空間,彼此是不同互相存取的除非你使用全域函式。
他就像一個公用櫃子一樣,只要你告訴別人我的東西放在幾號櫃子別人就可以來存取。
比如以下的代碼
int i=0;
int* p=&i;
現在p也可以修改i
*p = 1;
把它放到函式內就像這樣
void fun(int* p){
    *p = 1;
}
使用時就像這樣
fun(&i);

參考基本用法

底層裡面都是做指針的存取,使用方法怎麼區別可以這樣想像
參考就像一個不用輸入符號的指針
什麼意思呢,假設有一個指針為下
int i=0;
int* p=&i;
現在p也可以修改i
如果寫成參考就像這樣子
int i=0;
int& ali=i;
現在ali也可以修改i,現在操作ali就像在操作i
叫王小明的綽號 阿明 就像在叫王小明一樣。
放到函式可以省很多事情
void fun(int& p){
    p = 1;
}
使用時就像這樣
int i=0;
fun(i);
現在你在函式內的操作以及呼叫函式時的操作,全部都不用加上符號上了,是不是更好用呢?
或許你會在學到參考後一股腦地全部換參考,但其實他們之間大概有細微的差異

指針

  • 需要檢查有效性
  • 可以指向Null表示無效,也可以隨時更換指向的目標
  • 有指針的指針

參考

  • 不需檢查有效永遠有效
  • 不能換參考,且只能在宣告時給定目標
  • 沒有參考的參考
彙整出來的兩條守則:
  1. 不想付出檢查成本就用參考
  2. 需要更動指向的目標物或初始化為無效,只能用指針

活用參考與指針

很多時候他們是可以互相通用的,這可能不好記憶,透過練習題更容易熟悉,詳見以下的範例
有一個函式
  • 可以在函式內改他的值
  • 並使回傳的可以更改內容
看起來有些繞口,直接看代碼會比較好理解
要可以做到以下的樣板功能
int i;
fun(/*i*/);       //更改 i 的值
fun(/*i*/) += 10; //並加10
大致可以有以下四種做法,各字看一次,做一次應該10分鐘就可以入門參考與指針了
#include <iostream>
using namespace std;

int* fun1(int* i){
    *i = 1;
    return i;
}
int* fun2(int& i){
    i = 2;
    return &i;
}
int& fun3(int* i){
    *i = 3;
    return *i;
}
int& fun4(int& i){
    i = 4;
    return i;
}

int main() {
    int i=0;
    *fun1(&i) += 10;
    cout << "i=" << i << endl;
    *fun2(i) += 10;
    cout << "i=" << i << endl;
    fun3(&i) += 10;
    cout << "i=" << i << endl;
    fun4(i) += 10;
    cout << "i=" << i << endl;
    return 0;
}

2018年1月21日 星期日

C++ 如何引入已經寫好的 C 函式庫

C++ 如何引入已經寫好的 C 函式庫

只要告訴編譯器這一段是C語言就可以了,編譯器自己的會處理好,宣告方式如下
extern  "C"
需要把這一行加在函式的定義與宣告上,也就是 .c 與 .h 都要加上,可以使用括號涵蓋一個範圍
extern  "C" {
// Your code
}
如果這個函式庫是你正在開發的,還需需要被C的編譯器編譯就補上宏定義,讓代碼可以同時讓C與C++編譯器編譯
#ifdef  __cplusplus
extern  "C" {
#endif

// Your code

#ifdef  __cplusplus
}
#endif

範例

下面在C++檔案內引入C的檔案
// fileName : fun.h
#pragma once

#ifdef  __cplusplus
extern  "C" {
#endif

void fun();

#ifdef  __cplusplus
}
#endif
// fileName : fun.c
#ifdef  __cplusplus
extern  "C" {
#endif

#include <stdlib.h>
#include <stdio.h>    
void fun() {
    printf("c file \n");
}

#ifdef  __cplusplus
}
#endif
// fileName : main.cpp
#include <iostream>
#include "fun.h"

int main(int argc, char const *argv[]){
    fun();
    return 0;
}

原因

C++ 多了重載的功能,對於函式名稱的解析規則與C不一樣
對於C來說
fun(int, int); 與 fun(char, char); 都是解析成同一個 _foo
對C++來說則是解析成
fun(int, int); -> _fun_int_int
fun(char, char); -> _fun_char_char
這也正是可以多載的原因,如果加了修飾子則可以使用C的規則解析。
比如說上面的範例的C檔案沒有加入 extern “C” ,C++檔案直接引入 .h,這時候 fun.h 裡面的宣告是複製貼到 main.cpp 上,解析是看檔名,該份檔案是.cpp會被解析成 _fun_int_int ,則 fun.c 編譯的時候則被解析成 _fun 這時候名字就對不上了。

參考