2014年11月5日 星期三

(教學)Visual C++ 2005程式設計:如何實作一個Auto Number Generator的繁體中文版

//Auto Number Generator Electronic List
//ANG_Prototype.cpp
//by詹宗運
//免費授權Microsoft公司進行進一步的修改與工業化
//用來攤平記憶體缺損所造成的工業損失
//並且提供Visual C++社群做為討論與修改的使用
//version: Visual C++ 2005繁體中文版



最近科技業界常常出現科技公司老闆過勞死或是生病的新聞,
蘋果公司的iphone也常常當機而且記憶體出問題。
這是因為處理記憶體缺損是一項工業技術,
科技業老闆為了處理記憶體缺損所投入的時間與人力非常龐大,
最後都生病了。
其實筆者曾經在汐止科學園區上班,
筆者認為這些美國電腦系統的問題應該交還給美國科技業,
台灣應該做的是回報問題,
工業化以及商業化則應該交還給美國原廠去處理,
以台灣的資訊業人力數量來說並沒有美國那麼多人,
所以我們應該量力而為,
做好能力所及的事情就好,
並且要回報問題給美國原廠。

處理記憶體缺損並不是一件壞事,
使用MyErrorHandler事實上可以處理很多工業問題,
所以程式設計師有必要掌握程式設計的技術。
筆者並不缺錢,
利用這幾年空閒的時間開發小型程式,
現在正是創新與交棒給下一代2014程式設計師的時候了。
現在特別拿到網站上面公布,
這裡有AutoNumberGeneratorElectronicList的繁體中文新版,
這個程式可以產生自動號碼,
自動號碼就如同有了樂透號碼的全部組合,
如果電腦公司妥善的運用,
就可以利用這個程式開發出無限的資金,
例如樂透公司發行彩券創造收入就是一個方式。
微軟公司目前正在推廣無上限的雲端硬碟,
只要利用本程式工業化以後產生大量的自動號碼,
也可以很快的填滿微軟所有的硬碟,
歡迎公司行號推廣與利用這個程式碼。
也免費授權Microsoft微軟公司進行進一步的修改與工業化,
用來攤平記憶體缺損所造成的工業損失,
並且提供Visual C++社群做為討論與修改的使用。
version: Visual C++ 2005繁體中文版

使用方式:
建立一個Visual C++ 2005 WIN32主控台程式專案,
名稱設定成"ANG_Prototype"。
這時候會自動生成ANG_Prototype.cpp與stdafx.h
再建立一個空白標頭檔案名稱為"arrays.h"
然後把下面的ANG_Prototype.cpp與arrays.h所有文字內容,
分別拷貝貼上到你的同樣名稱的空白檔案裡面,
就可以使用了,
歡迎公司行號利用本程式提到的技術開發更高規模的工業化程式,
拼經濟救台灣。

//------------以下是stdafx.h程式碼
// stdafx.h : 可在此標頭檔中包含標準的系統 Include 檔,
// 或是經常使用卻很少變更的
// 專案專用 Include 檔案
//

#pragma once

#ifndef _WIN32_WINNT // 允許使用 Windows XP (含) 以後版本的特定功能。
#define _WIN32_WINNT 0x0501 // 將它變更為針對 Windows 其他版本的適當值。
#endif

#include <stdio.h>
#include <tchar.h>



// TODO: 在此參考您的程式所需要的其他標頭



//------------以下是arrays.h程式碼
/*
   Array Data Structure
   Chapter 2
   Data Structures for Game Developers
   Created by Allen Sherrod
*/


#include<cassert>


#ifndef _ARRAYS_H_
#define _ARRAYS_H_


template<typename T>
class UnorderedArray
{
   public:
      UnorderedArray(int size, int growBy = 1) :
                     m_array(NULL), m_maxSize(0),
                     m_growSize(0), m_numElements(0)
      {
         if(size)
            {
               m_maxSize = size;
               m_array = new T[m_maxSize];
               memset(m_array, 0, sizeof(T) * m_maxSize);

               m_growSize = ((growBy > 0) ? growBy : 0);
            }
      }

      ~UnorderedArray()
      {
         if(m_array != NULL)
            {
               delete[] m_array;
               m_array = NULL;
            }
      }

      void push(T val)
      {
         assert(m_array != NULL);

         if(m_numElements >= m_maxSize)
            {
               Expand();
            }

         m_array[m_numElements] = val;
         m_numElements++;
      }

      void pop()
      {
         if(m_numElements > 0)
            m_numElements--;
      }

      void remove(int index)
      {
         assert(m_array != NULL);

         if(index >= m_maxSize)
            {
               return;
            }

         for(int k = index; k < m_maxSize - 1; k++)
            m_array[k] = m_array[k + 1];
   
         m_maxSize--;

         if(m_numElements >= m_maxSize)
            m_numElements = m_maxSize - 1;
      }

      T& operator[](int index)
      {
         assert(m_array != NULL && index <= m_numElements);
         return m_array[index];
      }

      int search(T val)
      {
         assert(m_array != NULL);

         for(int i = 0; i < m_numElements; i++)
            {
               if(m_array[i] == val)
                  return i;
            }

         return -1;
      }

      void clear()      { m_numElements = 0; }
      int GetSize()     { return m_numElements; }
      int GetMaxSize()  { return m_maxSize; }
      int GetGrowSize() { return m_growSize; }

      void SetGrowSize(int val)
      {
         assert(val >= 0);
         m_growSize = val;
      }

   private:
      bool Expand()
      {
         if(m_growSize <= 0)
            return false;

         T *temp = new T[m_maxSize + m_growSize];
         assert(temp != NULL);

         memcpy(temp, m_array, sizeof(T) * m_maxSize);

         delete[] m_array;
         m_array = temp;

         m_maxSize += m_growSize;

         return true;
      }

   private:
      T *m_array;

      int m_maxSize;
      int m_growSize;
      int m_numElements;
};


template <typename T>
class OrderedArray
{
   public:
      OrderedArray(int size, int growBy = 1) :
                   m_array(NULL), m_maxSize(0),
                   m_growSize(0), m_numElements(0)
      {
         if(size)
            {
               m_maxSize = size;
               m_array = new T[m_maxSize];
               memset(m_array, 0, sizeof(T) * m_maxSize);

               m_growSize = ((growBy > 0) ? growBy : 0);
            }
      }

      ~OrderedArray()
      {
         if(m_array != NULL)
            {
               delete[] m_array;
               m_array = NULL;
            }
      }

      int push(T val)
      {
         assert(m_array != NULL);

         if(m_numElements >= m_maxSize)
            {
               Expand();
            }

         int i, k;

         for(i = 0; i < m_numElements; i++)
            {
               if(m_array[i] > val)
                  break;
            }

         for(k = m_numElements; k > i; k--)
            {
               m_array[k] = m_array[k - 1];
            }

         m_array[i] = val;
         m_numElements++;

         return i;
      }

      void pop()
      {
         if(m_numElements > 0)
            m_numElements--;
      }

      void remove(int index)
      {
         assert(m_array != NULL);

         if(index >= m_maxSize)
            {
               return;
            }

         for(int k = index; k < m_maxSize - 1; k++)
            m_array[k] = m_array[k + 1];
   
         m_maxSize--;

         if(m_numElements >= m_maxSize)
            m_numElements = m_maxSize - 1;
      }

      // Making this const allows for reading but not writing.
      const T& operator[](int index)
      {
         assert(m_array != NULL && index <= m_numElements);
         return m_array[index];
      }

      int search(T searchKey)
      {
         assert(m_array != NULL);

         int lowerBound = 0;
         int upperBound = m_numElements - 1;
         int current = 0;

         while(1)
            {
               current = (lowerBound + upperBound) >> 1;
             
               if(m_array[current] == searchKey)
                  {
                     return current;
                  }
               else if(lowerBound > upperBound)
                  {
                     return -1;
                  }
               else
                  {
                     if(m_array[current] < searchKey)
                        lowerBound = current + 1;
                     else
                        upperBound = current - 1;
                  }
            }

         return -1;
      }

      void clear()      { m_numElements = 0; }
      int GetSize()     { return m_numElements; }
      int GetMaxSize()  { return m_maxSize; }
      int GetGrowSize() { return m_growSize; }

      void SetGrowSize(int val)
      {
         assert(val >= 0);
         m_growSize = val;
      }

   private:
      bool Expand()
      {
         if(m_growSize <= 0)
            return false;

         T *temp = new T[m_maxSize + m_growSize];
         assert(temp != NULL);

         memcpy(temp, m_array, sizeof(T) * m_maxSize);

         delete[] m_array;
         m_array = temp;

         m_maxSize += m_growSize;

         return true;
      }

   private:
      T *m_array;

      int m_maxSize;
      int m_growSize;
      int m_numElements;
};


#endif
//---------------------------------------------------------------------

//---------------以下是ANG_Prototype.cpp程式碼
// ANG_prototype.cpp : 定義主控台應用程式的進入點。
//Auto Number Generator
//ANG_prototype.cpp
//by詹宗運
//免費授權Microsoft公司進行進一步的修改與工業化
//用來攤平記憶體缺損所造成的工業損失
//並且提供VC++社群做為討論與修改的使用
//version: Visual C++ 2005

#include "stdafx.h"

typedef struct a4element
{
int identity;
int a_content[3];
} A4element;



#include <windows.h>//myerrorhandler
#include <stdarg.h>//myerrorhandler
#include <stdio.h>//cout
#include <rtcapi.h>//myerrorhandler

#include <ostream>//fopen


#include <stdlib.h>//calloc
#include <iostream>//cout
#include <iomanip>//setw()






#include <fstream>
#include <memory.h>//typeinfo
#include <typeinfo>//typeinfo
#include <string.h>//string
#include <cstring>//string
#include <cstddef>//string







#define MAXQUEEN 7//定義最大堆疊容量,如果要超過10請修改switch case敘述
#define TRUE 1
#define FALSE 0
#define SOLUTION 5040//SOLUTION = (MAXQUEEN)! 例如5!=120, 3!=6,4!=24
#define ARRAYSIZE 8//ARRAYSIZE = MAXQUEEN+1
using namespace std;
int queen[MAXQUEEN];//存放8個皇后之列位置
int number=0;//計算總共有幾組解的總數
//決定皇后存放的位置
//輸出所需要的結果
#include "arrays.h"
UnorderedArray<int> array(4);




int SNum[SOLUTION][MAXQUEEN];//SNum = SolutionNumber
char SChar[SOLUTION][MAXQUEEN];//SChar = SolutionChar
char buf[SOLUTION*MAXQUEEN];//buf = bufferNumber

int remain;//remain = remain number

int calculate(int ,int);

#pragma runtime_checks("", off)

void print_table()
{
     int x=0,y=0;
     number+=1;


remain = SOLUTION-number;


     cout<<"自動產生"<<MAXQUEEN<<"個號碼組合的第"\
<<setw(7)<<number<<\
"組號碼,進度為剩下"<<remain<<\
"組尚未處理。"<<endl<<"\t";


int k=0;
for(x=0;x<MAXQUEEN;x++)
     {
        for(y=0;y<MAXQUEEN;y++)
           if(x==queen[y])
  {
k=y+1;
  array.push(k);
  }

     }


}



void decide_position(int value)
{
   int i=0;// i=行
   while(i<MAXQUEEN)
   {
   //是否受到攻擊的判斷式
      if(calculate(i,value)!=TRUE)
      {
         queen[value]=i;//只有在未受攻擊時將計算值存入皇后陣列

         if(value==MAXQUEEN-1)//列已到末端
            print_table();//只有在未受攻擊時列已到末端時才印出結果
         else
            decide_position(value+1);//只有在未受攻擊時將計算值存入皇后陣列,
//計算完成以後,列+1遞迴重新執行函數( value=列)

      }
 //受攻擊時值不能存入陣列
      i++;//不論是否遭受攻擊都換行重新執行函數 i=行
   }  
}
//0,0 i++
//1,0 queen[0]=1
//1,1 flag=1,i++
//2,1 queen[1]=2
//2,2 flag=1,i++


//資料來源:VC++資料結構教科書
//測試在(row,col)上的皇后是否遭受攻擊
//若遭受攻擊則傳回值為1,否則傳回0
int calculate(int row,int col)
{
    int i=0,flag=FALSE;
 
    while((flag!=TRUE)&&i<col)//當未遭受攻擊與i計算值小於VALUE
    {
     
       //判斷兩皇后是否在同一列在同一對角線上
     
       if((queen[i]==row))

  flag=TRUE;//只有在未受攻擊與計算值小於VALUE,
//當皇后陣列與待求VALUE相同時,判定遭受攻擊
       i++;//逐行檢查
    }
    return flag;
}

#pragma runtime_checks("", off)
//主程式
void construct_A4element(){

int f=0;
int g=0;
int h=0;

remain=0;


A4element *a=(A4element*)calloc(SOLUTION,sizeof(A4element));

while(f<SOLUTION)
{


while(g<(ARRAYSIZE-1))
{
a->identity=f;
a->a_content[g]=array[h];

cout<<"目前核對a["<<f<<"]->a_content["<<g<<"]="<<\
(a->a_content[g])<<endl;//顯示內容

SNum[f][g]=array[h];

//如果要超過10階乘就要加大下面這個switch case敘述
switch(SNum[f][g])
{
case 10:
SChar[f][g]='0';
break;
case 1:
SChar[f][g]='1';
break;
case 2:
SChar[f][g]='2';
break;
case 3:
SChar[f][g]='3';
break;
case 4:
SChar[f][g]='4';
break;
case 5:
SChar[f][g]='5';
break;
case 6:
SChar[f][g]='6';
break;
case 7:
SChar[f][g]='7';
break;
case 8:
SChar[f][g]='8';
break;
case 9:
SChar[f][g]='9';
break;

}


buf[h]=SChar[f][g];

h++;
g++;
}
g=0;
f++;
remain=SOLUTION - f;
cout<<"核對資料結構還剩下"<<remain<<"組。"<<endl;

}

cout<<"計算完成"<<endl;
system("pause");

//----------------------------------------------------------------------------

string str(SOLUTION*MAXQUEEN,' ');

cout<<"號碼產生的數量是 "<<h<<"個。"<<endl;

for(string::size_type ix=1;ix!=(string::size_type)(array.GetSize());++ix)
{
str[ix]=(char)array[ix];

}
cout<<"字串轉換完成。"<<endl;
system("pause");
//--------------------------------------------------------
//-------------make SNum----------------------------------

cout<<"計算SNum當中"<<endl;
int m=0;
int n=0;
int p=0;
    remain=0;

while(m<SOLUTION)
{
while(n<MAXQUEEN)
{
a->identity=m;
a->a_content[n]=array[p];

cout << "核對SNum[" <<m<< "]["<< n <<"]="<<(SNum[m][n])<<endl;
cout << "核對SChar["<<m<<"]["<<n<<"]="<<(SChar[m][n])<<endl;

SNum[m][n]=a->a_content[n];




p++;

n++;
}
n=0;
//---遞迴顯示自動號碼----
cout<<"這組自動號碼是:"<<endl;
for(int t=0;t<MAXQUEEN;t++)
cout<<SChar[m][t]<<" ";
cout<<endl;
//-----------------------
m++;
remain=SOLUTION-m;

cout<<"自動號碼已處理"<<m<<"組,剩下"<<remain<<"組"<<endl;

}
cout<<"自動號碼計算完成,開始輸出檔案到C硬碟。"<<endl;
cout<<"生成檔案名稱為c:\\AutoNumberGeneratorElectronicList.txt。"<<endl;
system("pause");

//--------------output------------------------------------

fstream outf(("c://AutoNumberGeneratorElectronicList.txt"),ios::out|ios::app);
//if(outf.fail())
// return;






if(buf[0]!='\0'){
outf.write(buf,sizeof(buf));
outf<<endl;

}

outf.close();

cout<<"輸出檔案完成。"<<endl;

cout<<"array的型態 = "<<typeid(array).name()<<endl;
cout<<"感謝Allen Sherrod先生的資料結構教科書,僅此致謝。"<<endl;
cout<<"Auto Number Generator: Visual C++ 2005版,"<<endl;
cout<<"詹宗運製作,"<<endl;
cout<<"免費授權Microsoft公司進行進一步的修改與工業化,"<<endl;
cout<<"用來攤平記憶體缺損所造成的工業損失,"<<endl;
cout<<"並且提供VC++社群做為討論與修改的使用。"<<endl;
system("pause");
free(a);

}




//主程式


#pragma runtime_checks("", off)

// RTC Error Handler
int MyErrorHandler(int errType, const char* file, int line,\
    const char* module, const char* format, ...)
{
    // 1. Prevent re-entrance
    static long IsRunning = 0;
    while ( InterlockedExchange(&IsRunning, 1) )
        Sleep(1);

    // 2. Get the RTC error number from the var_arg list
    va_list ArgList;
    va_start(ArgList, format);
    _RTC_ErrorNumber ErrorNumber = va_arg(ArgList, _RTC_ErrorNumber);
    va_end(ArgList);

    char s[1024];
    // 3. Get the error description
    const char* ErrorDesc = _RTC_GetErrDesc(ErrorNumber);
    sprintf_s(s, sizeof(s), "%s occured.\nLine: %i\
\nFile: %s\nModule: %s\nClick OK to break into debugger.",\
        ErrorDesc, line, file ? file : "Unknown",\
     module ? module : "Unknown");
 
// 4. Display message box
    MessageBoxA(NULL, s, "Run-Time Error", MB_OK);
    // 5. Go ahead and break into the debugger
    return 1;
}
#pragma runtime_checks("", restore)




int _tmain(int argc, _TCHAR* argv[])
{


cout<<"自動號碼生成器,詹宗運製作。"<<endl;
cout<<"接下來會自動運算出許多訊息,請耐心等待訊息停止以後,"<<endl;
cout<<"再按下按鍵繼續運算。"<<endl;
cout<<"開始運算,請準備。"<<endl;
system("pause");

_RTC_error_fn OldHandler;
    // Set new RTC error handler and save the old one
    OldHandler = _RTC_SetErrorFunc(&MyErrorHandler);



decide_position(0);
construct_A4element();

    _RTC_SetErrorFunc(OldHandler);
system("pause");


return 0;
}


//----------------------------------------------