周星星 阅读(5223) 评论(100)

专门保存代码片断


评论列表
周星星
[zt] C++中如何将一个数字三位三位加逗号?比如 1389992 输出为 1,389,992

bruceteen的方法(使用一个如此设置的local):
#include <iostream>
#include <locale>

int main( void )
{
    using namespace std;

    cout << 1389992 << endl; // 1389992

    locale chs( "chs" ); // chs在我这里行,不知道你那里怎么样
    cout.imbue( chs );
    cout << 1389992 << endl; // 1,389,992
}

特别推荐 namtso的方法(自己订制local):
#include <iostream>
#include <string>
#include <locale>
using namespace std;

class thousands_sep_facet:public std::numpunct<char>
{
public:
    explicit thousands_sep_facet( size_t r=0 ) : std::numpunct<char>(r)
    {
    }
protected:
    string do_grouping() const
    {
        return "\003";
    }
};

int main( void )
{
    cout << 1389992 << endl; // 1389992

    locale loc( locale(), new thousands_sep_facet );
    std::cout.imbue( loc );
    cout << 1389992 << endl; // 1,389,992

    return 0;
}

周星星
传递可变参数列表

#include <iostream>
using namespace std;

static void* funaddr_;
static void* retaddr_;
static int retvalue_;
__declspec(naked) int a( const char* _Format, ... )
{
    cout << "[Begin]" << endl;

    funaddr_ = &printf;
    __asm
    {
        pop retaddr_
        call funaddr_
        mov retvalue_, eax
        push retaddr_
    }

    cout << "[End]" << endl;

    __asm
    {
        mov eax, retvalue_;
        ret
    }
}

int main( void )
{
    int n = a( "%d\n", 123 );
    cout << n << endl;

    return 0;
}

周星星
给 [shuishi32]:
#include <iostream>
using namespace std;

struct Base
{
    virtual bool equal( const Base& lhs ) const
    {
        cout << "Base" << endl;
        return typeid(*this)==typeid(lhs) && (true); // (true) is only a test
    }
    bool operator==( const Base& lhs ) const
    {
        return equal(lhs);
    }
};
struct CA : Base
{
    virtual bool equal( const Base& lhs ) const
    {
        cout << "CA" << endl;
        return typeid(*this)==typeid(lhs) && (true); // (true) is only a test
    }
    bool operator==( const CA& lhs ) const
    {
        return equal(lhs);
    }
};
struct CB : Base
{
    virtual bool equal( const Base& lhs ) const
    {
        cout << "CB" << endl;
        return typeid(*this)==typeid(lhs) && (true); // (true) is only a test
    }
    bool operator==( const CB& lhs ) const
    {
        return equal(lhs);
    }
};

int main( void )
{
    Base *p1 = new CA;
    Base *p2 = new CB;
    Base *p3 = new CA;

    cout << ( (*p1)==(*p2) ) << endl;
    cout << ( (*p1)==(*p3) ) << endl;

    return 0;
}
周星星
给 [hhyang]:

#include <time.h>
#include <math.h>

bool lotus2time( double dtSrc, struct tm& tmDest )
{
    const long MIN_DATE = -657434L;
    const long MAX_DATE = 2958465L;
    const double HALF_SECOND = 1.0/172800.0;
    const long month_days[13] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};

    if( dtSrc>MAX_DATE || dtSrc<MIN_DATE )
        return false;

    bool bLeap4 = true;
    double dblDate = dtSrc + ((dtSrc > 0.0) ? HALF_SECOND : -HALF_SECOND);
    long nDays = (long)dblDate;
    long nDaysAbsolute = (long)dblDate + 693959L;
    dblDate = fabs(dblDate);
    long nSecsInDay = (long)((dblDate - floor(dblDate)) * 86400.);
    tmDest.tm_wday = (int)((nDaysAbsolute - 1) % 7L);
    long n400Years = (long)(nDaysAbsolute / 146097L);
    nDaysAbsolute %= 146097L;
    long n400Century = (long)((nDaysAbsolute - 1) / 36524L);

    long n4Years;
    long n4Day;
    if (n400Century != 0)
    {
        nDaysAbsolute = (nDaysAbsolute - 1) % 36524L;
        n4Years = (long)((nDaysAbsolute + 1) / 1461L);
        if (n4Years != 0)
            n4Day = (long)((nDaysAbsolute + 1) % 1461L);
        else
        {
            bLeap4 = false;
            n4Day = (long)nDaysAbsolute;
        }
    }
    else
    {
        n4Years = (long)(nDaysAbsolute / 1461L);
        n4Day = (long)(nDaysAbsolute % 1461L);
    }

    long n4Yr;
    if (bLeap4)
    {
        n4Yr = (n4Day - 1) / 365;

        if (n4Yr != 0)
            n4Day = (n4Day - 1) % 365;
    }
    else
    {
        n4Yr = n4Day / 365;
        n4Day %= 365;
    }

    tmDest.tm_yday = (int)n4Day + 1;
    tmDest.tm_year = n400Years * 400 + n400Century * 100 + n4Years * 4 + n4Yr;

    if (n4Yr == 0 && bLeap4)
    {
        if (n4Day == 59)
        {
            tmDest.tm_mon = 2;
            tmDest.tm_mday = 29;
            goto DoTime;
        }

        if (n4Day >= 60)
            --n4Day;
    }

    ++n4Day;

    for (tmDest.tm_mon = (n4Day >> 5) + 1;
        n4Day > month_days[tmDest.tm_mon]; tmDest.tm_mon++);

    tmDest.tm_mday = (int)(n4Day - month_days[tmDest.tm_mon-1]);

DoTime:
    if (nSecsInDay == 0)
        tmDest.tm_hour = tmDest.tm_min = tmDest.tm_sec = 0;
    else
    {
        tmDest.tm_sec = (int)nSecsInDay % 60L;
        long nMinutesInDay = nSecsInDay / 60L;
        tmDest.tm_min = (int)nMinutesInDay % 60;
        tmDest.tm_hour = (int)nMinutesInDay / 60;
    }

    tmDest.tm_mon -= 1;
    tmDest.tm_year -= 1900;
    tmDest.tm_yday -= 1;
    tmDest.tm_isdst = 0;
    return true;
}

#include <stdio.h>
int main()
{
    struct tm t;
    lotus2time( 39354.849004629628, t );
   
    printf( "%04d-%02d-%02d %02d:%02d:%02d\n", t.tm_year+1900, t.tm_mon+1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec );
    printf( "星期%d, 本年第%d天\n", t.tm_wday, t.tm_yday+1 );

    return 0;
}

周星星
控制台测试


//#include <stdio.h>
//#include <conio.h>
//
//int main( )
//{
//    for( ; ; )
//    {
//        int n = _getch();
//        switch( n )
//        {
//        case 0x00:
//        case 0xE0:
//            printf( "%02X %02X\n", n, _getch() );
//            break;
//        default:
//            printf( "%02X\n", n );
//        }
//    }
//
//    return 0;
//}

#include <windows.h>
#include <stdio.h>

BOOL WINAPI csl_handler_routine( DWORD CtrlType )
{
    switch( CtrlType )
    {
    case CTRL_C_EVENT:
    case CTRL_BREAK_EVENT:
    case CTRL_CLOSE_EVENT:
    case CTRL_LOGOFF_EVENT:
    case CTRL_SHUTDOWN_EVENT:
        // release resource
        SetConsoleCtrlHandler( &csl_handler_routine, FALSE );
        break;
    }
    return FALSE;
}

HANDLE hOutput_ = ::GetStdHandle(STD_OUTPUT_HANDLE);
HANDLE hInput_ = ::GetStdHandle(STD_INPUT_HANDLE);
COORD dwSize = { 60, 16 };
SHORT baselinenum = 0;

BOOL SetCursorPosition( SHORT x, SHORT y )
{
    COORD cd = { x, y+baselinenum };
    return ::SetConsoleCursorPosition( hOutput_, cd );
}

BOOL EarseTail( void )
{
    CONSOLE_SCREEN_BUFFER_INFO info;
    BOOL f = ::GetConsoleScreenBufferInfo( hOutput_, &info );
    printf( "%*s", dwSize.X-info.dwCursorPosition.X, "" );
    return f;
}

BOOL SetTextAttrib( WORD wAttributes )
{
    return ::SetConsoleTextAttribute( hOutput_, wAttributes );
}

void ShowControlKeyState( DWORD dwControlKeyState )
{
    SetTextAttrib( FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_RED );
    printf( "" ); EarseTail();
    printf( "CAPS LOCK  : %s", (dwControlKeyState&CAPSLOCK_ON       )?"ON":"OFF" ); EarseTail();
    printf( "Enhanced   : %s", (dwControlKeyState&ENHANCED_KEY      )?"ON":"OFF" ); EarseTail();
    printf( "ALT Left   : %s", (dwControlKeyState&LEFT_ALT_PRESSED  )?"ON":"OFF" ); EarseTail();
    printf( "CTL Left   : %s", (dwControlKeyState&LEFT_CTRL_PRESSED )?"ON":"OFF" ); EarseTail();
    printf( "NUM LOCK   : %s", (dwControlKeyState&NUMLOCK_ON        )?"ON":"OFF" ); EarseTail();
    printf( "ALT Right  : %s", (dwControlKeyState&RIGHT_ALT_PRESSED )?"ON":"OFF" ); EarseTail();
    printf( "CTL Right  : %s", (dwControlKeyState&RIGHT_CTRL_PRESSED)?"ON":"OFF" ); EarseTail();
    printf( "SCROLL LOCK: %s", (dwControlKeyState&SCROLLLOCK_ON     )?"ON":"OFF" ); EarseTail();
    printf( "Shift      : %s", (dwControlKeyState&SHIFT_PRESSED     )?"ON":"OFF" ); EarseTail();
}
void ShowMouseInfo( MOUSE_EVENT_RECORD& mer )
{
    SetTextAttrib( FOREGROUND_BLUE|FOREGROUND_GREEN/*|FOREGROUND_RED*/ | FOREGROUND_INTENSITY );
    printf( "MousePosition: %03hd, %03hd", mer.dwMousePosition.X, mer.dwMousePosition.Y );                                                                       EarseTail();
    printf( "ButtonState:   Left=%c Right=%c", (mer.dwButtonState&FROM_LEFT_1ST_BUTTON_PRESSED)?'T':'F', (mer.dwButtonState&RIGHTMOST_BUTTON_PRESSED)?'T':'F' ); EarseTail();
    printf( "EventFlags:    " );
    switch( mer.dwEventFlags )
    {
    case 0            : printf( "Pressed or Released" ); EarseTail(); break;
    case DOUBLE_CLICK : printf( "double click       " ); EarseTail(); break;
    case MOUSE_MOVED  : printf( "mouse moved        " ); EarseTail(); break;
    case MOUSE_WHEELED: printf( "mouse wheeled      " ); EarseTail(); break;
    }

    ShowControlKeyState( mer.dwControlKeyState );
}

void ShowKeyInfo( KEY_EVENT_RECORD& ker )
{
    SetTextAttrib( FOREGROUND_BLUE/*|FOREGROUND_GREEN*/|FOREGROUND_RED | FOREGROUND_INTENSITY );
    printf( "KeyDown:          %c , Repeat Count:     %d", ker.bKeyDown?'T':'F', ker.wRepeatCount );       EarseTail();
    printf( "VirtualKeyCode:   %02X, wVirtualScanCode: %02X", ker.wVirtualKeyCode, ker.wVirtualScanCode ); EarseTail();
    printf( "AsciiChar:        %c", ker.uChar.AsciiChar );                                                 EarseTail();

    ShowControlKeyState( ker.dwControlKeyState );
}

int main( )
{
    // quit ctrl
    SetConsoleCtrlHandler( &csl_handler_routine, TRUE );

    // set window title
    ::SetConsoleTitle( TEXT("Test") );

    // get begin line number
    CONSOLE_SCREEN_BUFFER_INFO sinfo;
    ::GetConsoleScreenBufferInfo( hOutput_, &sinfo );
    baselinenum = sinfo.dwCursorPosition.Y;

    // hide cursor
    CONSOLE_CURSOR_INFO cinfo;
    ::GetConsoleCursorInfo( hOutput_, &cinfo );
    cinfo.bVisible = FALSE;
    ::SetConsoleCursorInfo( hOutput_, &cinfo );

    // set window size
    SMALL_RECT winsize = { 0, 0, dwSize.X-1, dwSize.Y-1 };
    ::SetConsoleWindowInfo( hOutput_, TRUE, &winsize );
    ::SetConsoleScreenBufferSize( hOutput_, dwSize );

    // enable mouse & window
    DWORD mode;
    ::GetConsoleMode( hInput_, &mode );
    mode |= ( ENABLE_MOUSE_INPUT | ENABLE_WINDOW_INPUT );
    ::SetConsoleMode( hInput_, mode );

    // get mouse & key
    INPUT_RECORD ir;
    DWORD index = 1;
    for( DWORD n; ReadConsoleInput(hInput_,&ir,1,&n); ++index )
    {
        SetCursorPosition( 0, 0);
        printf( "%d", index ); EarseTail();

        switch( ir.EventType )
        {
        case MOUSE_EVENT:
            ShowMouseInfo( ir.Event.MouseEvent );
            break;
        case KEY_EVENT:
            ShowKeyInfo( ir.Event.KeyEvent );
            break;
        }
    }

    // release resource
    // restore console setting

    return 0;
}

 

周星星
获取鼠标所在位置的颜色值


#include <stdio.h>
#include <assert.h>
#include <windows.h>

HANDLE hInput;
HANDLE hOutput;
CONSOLE_CURSOR_INFO cursor_info;
CONSOLE_SCREEN_BUFFER_INFO screen_info;
DWORD mode;

// 设置控制台
void Init( void )
{
    // 得到控制台输入输出句柄
    hInput  = ::GetStdHandle(STD_INPUT_HANDLE);
    hOutput = ::GetStdHandle(STD_OUTPUT_HANDLE);
    assert( hInput  != INVALID_HANDLE_VALUE );
    assert( hOutput != INVALID_HANDLE_VALUE );

    // 隐藏光标
    BOOL f = ::GetConsoleCursorInfo( hOutput, &cursor_info );
    assert( f );
    CONSOLE_CURSOR_INFO cursor_info_new = cursor_info;
    cursor_info_new.bVisible = FALSE;
    f = ::SetConsoleCursorInfo( hOutput, &cursor_info_new );
    assert( f );

    // 得到控制台输出银屏缓冲信息
    ::GetConsoleScreenBufferInfo( hOutput, &screen_info );

    // 允许鼠标输入
    f = ::GetConsoleMode( hInput, &mode );
    assert( f );
    f = ::SetConsoleMode( hInput, mode|ENABLE_MOUSE_INPUT );
    assert( f );
}

// 复原控制台
void restore( void )
{
    ::SetConsoleMode( hInput, mode );
    ::SetConsoleCursorInfo( hOutput, &cursor_info );
    COORD cd = { 0, screen_info.dwCursorPosition.Y+2 };
    ::SetConsoleCursorPosition( hOutput, cd );
}

// 用于处理ctrl+c方式的退出
BOOL WINAPI CTRL_C_Routine( DWORD dwCtrlType )
{
    if( dwCtrlType == CTRL_C_EVENT )
    {
        // 复原控制台各项属性
        restore();
        // 卸载CTRL+C处理函数
        ::SetConsoleCtrlHandler( &CTRL_C_Routine, FALSE );
    }

    return FALSE;
}

// 获取鼠标所在位置的点颜色
int main( void )
{
    // 初始化控制台各项属性
    Init();

    // 安装CTRL+C处理函数
    BOOL f = ::SetConsoleCtrlHandler( &CTRL_C_Routine, TRUE );
    assert( f );

    // 得到桌面DC
    HWND hwnd = ::GetDesktopWindow();
    HDC hdc = ::GetWindowDC( hwnd );
    assert( hdc != 0 );

    // 提示信息
    puts( "press ESC key to quit." );
    puts( "press mouse left key and move ..." );

    // 获得键盘及鼠标输入
    INPUT_RECORD ir;
    for( DWORD n; ReadConsoleInput(hInput,&ir,1,&n) && n==1; )
    {
        // 跳到第1行第0列
        COORD cd = { 0, screen_info.dwCursorPosition.Y+1 };
        f = ::SetConsoleCursorPosition( hOutput, cd );
        assert( f );

        if( ir.EventType == MOUSE_EVENT ) // 鼠标信息
        {
            if( ir.Event.MouseEvent.dwEventFlags == MOUSE_MOVED ) // 鼠标移动
            {
                if( ir.Event.MouseEvent.dwButtonState&FROM_LEFT_1ST_BUTTON_PRESSED ) // 鼠标左键按下
                {
                    // 得到鼠标位置(非控制台)
                    POINT pt;
                    f = ::GetCursorPos( &pt );
                    assert( f );
                    // 得到鼠标颜色
                    COLORREF rgb = ::GetPixel( hdc, pt.x, pt.y );
                    assert( rgb != CLR_INVALID );
                    // 输出信息
                    int num = printf( "POINT(%ld,%ld): RGB(%u,%u,%u)", pt.x, pt.y, GetRValue(rgb), GetGValue(rgb), GetBValue(rgb) );
                    // 擦除尾部残余
                    printf( "%*s", screen_info.dwSize.X-num, "" );
                }
                else
                {
                    // 提示信息
                    int num = printf( "%s", "press mouse left key and move ..." );
                    // 擦除尾部残余
                    printf( "%*s", screen_info.dwSize.X-num, "" );
                }
            }
        }
        else if( ir.EventType == KEY_EVENT ) // 键盘信息
        {
            if( ir.Event.KeyEvent.wVirtualKeyCode == 0x1B )
                break;
        }
    }

    // 复原控制台各项属性
    restore();
}

周星星
一个最简单的DLL例子:

建一个win32 dll空的工程,加入如下两个文件
//a.cpp
extern "C" __declspec(dllexport) int __stdcall test( int a, int b )
{
    return a+b;
}

//a.def
LIBRARY a
EXPORTS
    test @1

然后编译联结就得到 a.dll。
附:
a. 用 depends.exe 可以查看其导出函数。
b. 如果是vc8,需要打开工程属性页 configuration properties->Linker->Input->Module Definition File输入a.def
c. 如果需要进程线程控制,加入如下函数
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

周星星
显示进程树


#include <windows.h>
#include <tlhelp32.h>
#include <iostream>
#include <iomanip>
#include <list>
#pragma comment(lib, "psapi")

bool GetProcessList( std::list<PROCESSENTRY32>& pcslst )
{
    pcslst.clear();

    HANDLE hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
    if( hProcessSnap != INVALID_HANDLE_VALUE )
    {
        PROCESSENTRY32 pe32 = {0};
        pe32.dwSize = sizeof(PROCESSENTRY32);
        if( Process32First(hProcessSnap,&pe32) )
        {
            do
            {
                pcslst.push_back( pe32 );
            }
            while( Process32Next(hProcessSnap,&pe32) );
            CloseHandle( hProcessSnap );
            return true;
        }
        CloseHandle( hProcessSnap );
    }
    return false;
}
void ShowProcessList( void )
{
    std::list<PROCESSENTRY32> pcslst;
    if( GetProcessList(pcslst) )
    {
        for( std::list<PROCESSENTRY32>::iterator itor=pcslst.begin(); itor!=pcslst.end(); ++itor )
        {
            std::cout << itor->th32ParentProcessID << " " << itor->th32ProcessID << " " << itor->szExeFile << '\n';
        }
    }
}
void ShowProcessTree( void )
{
    using namespace std;

    struct ShowSubProcessTree
    {
        void operator()( std::list<PROCESSENTRY32>& pcslst, PROCESSENTRY32& pe32, std::streamsize spacenum )
        {
            cout << setw(spacenum) << setfill(' ') << "";
            cout << pe32.th32ProcessID << ": " << pe32.szExeFile << '\n';

            for( std::list<PROCESSENTRY32>::iterator itor=pcslst.begin(); itor!=pcslst.end(); ++itor )
            {
                if( itor->th32ProcessID!=itor->th32ParentProcessID && itor->th32ParentProcessID==pe32.th32ProcessID )
                {
                    ShowSubProcessTree()( pcslst, *itor, spacenum+4 );
                }
            }
        }
    };

    std::list<PROCESSENTRY32> pcslst;
    if( GetProcessList(pcslst) )
    {
        for( std::list<PROCESSENTRY32>::iterator itor=pcslst.begin(); itor!=pcslst.end(); ++itor )
        {
            bool bHaveParent = false;
            for( std::list<PROCESSENTRY32>::iterator itor2=pcslst.begin(); itor2!=pcslst.end(); ++itor2 )
            {
                if( itor2!=itor && itor2->th32ProcessID==itor->th32ParentProcessID )
                {
                    bHaveParent = true;
                    break;
                }
            }
            if( !bHaveParent )
            {
                ShowSubProcessTree()( pcslst, *itor, 0 );
            }
        }
    }
}

int main(void)
{
    //ShowProcessList();
    ShowProcessTree();

    return 0;
}

周星星
GradientFill 用法事例

#define _WIN32_WINNT 0x0501
#include <windows.h>
#pragma comment( lib, "Msimg32" )

void MyFill( HDC hdc, const RECT& rt, COLORREF c1, COLORREF c2 )
{
    TRIVERTEX rcVertex[2] = { {rt.left,rt.top,GetRValue(c1)<<8,GetGValue(c1)<<8,GetBValue(c1)<<8,0}, {rt.right,rt.bottom,GetRValue(c2)<<8,GetGValue(c2)<<8,GetBValue(c2)<<8,0} };
    GRADIENT_RECT grect[1] = { {0,1} };

    GradientFill( hdc, rcVertex, _countof(rcVertex), grect, _countof(grect), GRADIENT_FILL_RECT_V );
}

int main( )
{
    HWND hwnd = ::GetConsoleWindow();
    RECT rt;
    ::GetWindowRect( hwnd, &rt );
    rt.right-=rt.left;rt.left=0; rt.bottom-=rt.top;rt.top=0;
    HDC hdc = ::GetWindowDC( hwnd );

    MyFill( hdc, rt, RGB(255,0,0), RGB(255,255,255) ); // 由红到白

    return 0;
}

周星星
re: 代码片断
主人趋使着一群猎犬去逮兔子
犬A说:为了犬类的幸福,要多逮兔子,这样主人就会给犬类多赏几块骨头
犬B说:兔子杀光了,主人就会杀猎犬来吃肉了,为了犬类的幸福,要少逮兔子
这下子两帮兔子闹开了,互相骂:汉奸,愤青,卖国贼

屠夫拿着屠刀来到猪圈,其他猪都吓得往后躲。
这时候,有一只聪明另类的猪,它献媚地对屠夫摇尾媚笑,本以为屠夫会放过它,可是屠夫却说了一句“其他猪都很‘良民’,你TMD却敢对我摆鬼脸,我砍了你”。
这只猪不知道自己是猪,“献媚”也要对方能理解才行呀,可对方没把它当人看,自然也理解不了它的行为。
周星星
简单比较两个文件是否相同

#include <windows.h>

DWORD FileCompare( LPCTSTR fn1, LPCTSTR fn2, BOOL& bOutput )
{
    // 未做的优化步骤:将文件名转为绝对路径,再转为长文件名,比较两文件名是否相同,如果相同直接返回

    HANDLE hFile1=INVALID_HANDLE_VALUE, hFile2=INVALID_HANDLE_VALUE;
    __int64 qwLen1=0, qwLen2=0;
    DWORD dwAG;
    HANDLE hFileMapping1=NULL, hFileMapping2=NULL;
    LPVOID lp1=NULL, lp2=NULL;
    DWORD dwRet = 0;

    hFile1 = CreateFile( fn1, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL );
    if( INVALID_HANDLE_VALUE == hFile1 )
        goto error;

    BOOL b1 = GetFileSizeEx( hFile1, (PLARGE_INTEGER)&qwLen1 );
    if( !b1 )
        goto error;

    hFile2 = CreateFile( fn2, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL );
    if( INVALID_HANDLE_VALUE == hFile2 )
        goto error;

    BOOL b2 = GetFileSizeEx( hFile2, (PLARGE_INTEGER)&qwLen2 );
    if( !b2 )
        goto error;

    if( qwLen1 != qwLen2 )
    {
        bOutput = FALSE;
        goto right;
    }
    if( qwLen1 == 0 )
    {
        bOutput = TRUE;
        goto right;
    }

    hFileMapping1 = CreateFileMapping( hFile1,NULL,PAGE_READONLY, 0, 0, NULL );
    if( NULL == hFileMapping1 )
        goto error;

    hFileMapping2 = CreateFileMapping( hFile2,NULL,PAGE_READONLY, 0, 0, NULL );
    if( NULL == hFileMapping2 )
        goto error;

    SYSTEM_INFO sinf;
    GetSystemInfo( &sinf );
    dwAG = sinf.dwAllocationGranularity;

    for( __int64 qwOffset=0; qwOffset<qwLen1; qwOffset+=dwAG )
    {
        size_t size = (size_t)( (qwOffset+dwAG > qwLen1) ? (qwLen1-qwOffset) : dwAG );

        lp1 = MapViewOfFile( hFileMapping1, FILE_MAP_READ, (DWORD)(qwOffset>>32), (DWORD)(qwOffset&0xFFFFFFFF), size );
        if( NULL == lp1 )
            goto error;

        lp2 = MapViewOfFile( hFileMapping2, FILE_MAP_READ, (DWORD)(qwOffset>>32), (DWORD)(qwOffset&0xFFFFFFFF), size );
        if( NULL == lp2 )
            goto error;

        if( 0 != memcmp(lp1,lp2,size) )
        {
            bOutput = FALSE;
            goto right;
        }

        UnmapViewOfFile( lp1 );
        lp1 = 0;

        UnmapViewOfFile( lp2 );
        lp2 = 0;
    }
    bOutput = TRUE;
    goto right;


error:
    dwRet = GetLastError();
    goto leave;
right:
    dwRet = 0;
    goto leave;
leave:
    if( NULL != lp1 )
        UnmapViewOfFile( lp1 );
    if( NULL != hFileMapping1 )
        CloseHandle( hFileMapping1 );
    if( INVALID_HANDLE_VALUE != hFile1 )
        CloseHandle( hFile1 );
   
    if( NULL != lp2 )
        UnmapViewOfFile( lp2 );
    if( NULL != hFileMapping2 )
        CloseHandle( hFileMapping2 );
    if( INVALID_HANDLE_VALUE != hFile2 )
        CloseHandle( hFile2 );

    return dwRet;
}

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

int main( void )
{
    LPCTSTR fn1 = TEXT("f:\\a.txt"); // TEXT("F:\\windows\\temp\\L.tmp");
    LPCTSTR fn2 = TEXT("f:\\a.txt"); // TEXT("F:\\windows\\temp\\R.tmp");
    BOOL isequ = FALSE;
    DWORD ret = FileCompare( fn1, fn2, isequ );
    if( ret == 0 )
    {
        if( isequ )
        {
            _tprintf( TEXT("Identical\n") );
        }
        else
        {
            _tprintf( TEXT("Different\n") );
        }
    }
    else
    {
        LPTSTR lpBuffer;
        FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_IGNORE_INSERTS|FORMAT_MESSAGE_FROM_SYSTEM
            , NULL
            , ret
            , LANG_NEUTRAL
            , (LPTSTR)&lpBuffer
            , 0
            , NULL );
        _tprintf( TEXT("error: %s"), lpBuffer );
        LocalFree( lpBuffer );
    }

    return 0;
}

周星星
SysTreeView32 事例


#include <windows.h>
#include <tchar.h>
#include <commctrl.h>
#pragma comment(lib,"comctl32.lib")
#include "resource.h"

LPCTSTR szTitle = TEXT("CPP22");
LPCTSTR szWindowClass = TEXT("CPP22");
HINSTANCE hInst;
HWND m_hwndTree;
HIMAGELIST m_hilTree;

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int __stdcall _tWinMain( HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR /*lpCmdLine*/, int nCmdShow )
{
    hInst = hInstance;

    WNDCLASSEX wcex;
    wcex.cbSize        = sizeof(WNDCLASSEX);
    wcex.style         = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc   = WndProc;
    wcex.cbClsExtra    = 0;
    wcex.cbWndExtra    = 0;
    wcex.hInstance     = hInstance;
    wcex.hIcon         = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_CPP22));
    wcex.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName  = MAKEINTRESOURCE(IDC_CPP22);
    wcex.lpszClassName = szWindowClass;
    wcex.hIconSm       = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
    RegisterClassEx(&wcex);

    HWND hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

    { // here you are
        RECT rc;
        ::GetClientRect(hWnd, &rc);
        m_hwndTree = CreateWindowEx( 0, WC_TREEVIEW, TEXT("TreeCtrl test")
         , WS_CHILD | WS_VISIBLE | TVS_HASLINES | TVS_SHOWSELALWAYS | TVS_HASBUTTONS
                                    , 1, 1, rc.right, rc.bottom
         , hWnd, 0, hInst, NULL );
        HFONT hfont = (HFONT)::SendMessage(hWnd, WM_GETFONT, 0, 0);
        ::SendMessage(m_hwndTree, WM_SETFONT, (WPARAM)hfont, MAKELPARAM(TRUE, 0));

        m_hilTree = ImageList_LoadBitmap( hInst, MAKEINTRESOURCE(IDB_CONTROL_IMAGELIST), 16, 0, RGB(255,0,255) );
        TreeView_SetImageList(m_hwndTree, m_hilTree, TVSIL_NORMAL);

        TreeView_DeleteAllItems(m_hwndTree);

        TV_INSERTSTRUCT tvis;
        tvis.hParent = TVI_ROOT;
        tvis.hInsertAfter = TVI_FIRST;
        tvis.item.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_STATE | TVIF_PARAM | TVIF_TEXT;
        tvis.item.state = TVIS_EXPANDED;
        tvis.item.stateMask = TVIS_EXPANDED;
        tvis.item.iImage = 0;
        tvis.item.iSelectedImage = 1;
        tvis.item.lParam = NULL;
        tvis.item.pszText = TEXT("root");
        HTREEITEM hroot = TreeView_InsertItem(m_hwndTree, &tvis);

        tvis.hInsertAfter = TVI_LAST;
        tvis.item.stateMask = TVIS_EXPANDED;
        for( int i=0; i<2; ++i )
        {
            tvis.hParent = hroot;
            tvis.item.iImage = 2;
            tvis.item.iSelectedImage = 3;
            tvis.item.lParam = NULL;
            tvis.item.state = 0;
            tvis.item.pszText = TEXT("sub");
            HTREEITEM hti = TreeView_InsertItem(m_hwndTree, &tvis);
            for( int j=0; j<2; ++j )
            {
                tvis.hParent = hti;
                tvis.item.iImage = 4;
                tvis.item.iSelectedImage = 5;
                tvis.item.lParam = NULL;
                tvis.item.state = 0;
                tvis.item.pszText = TEXT("sub2");
                HTREEITEM hti2 = TreeView_InsertItem(m_hwndTree, &tvis);
            }
        }
    }

    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);

    MSG msg;
    HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_CPP22));
    while (GetMessage(&msg, NULL, 0, 0))
    {
        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    return (int)msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_COMMAND:
        {
            int wmId    = LOWORD(wParam);
            int wmEvent = HIWORD(wParam);
            switch (wmId)
            {
            case IDM_EXIT:
                DestroyWindow(hWnd);
                break;
            default:
                return DefWindowProc(hWnd, message, wParam, lParam);
            }
        }
        break;
    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);
            EndPaint(hWnd, &ps);
        }
        break;
    case WM_SIZE:
        {
            UINT nType = (UINT)wParam;
            int cx = LOWORD(lParam);
            int cy = HIWORD(lParam);
            if (nType != SIZE_MINIMIZED)
                MoveWindow(m_hwndTree, 1, 1, cx, cy, TRUE);
        }
        break;
    case WM_DESTROY:
        {
            ImageList_Destroy(m_hilTree);
            PostQuitMessage(0);
        }
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

 

周星星
虚线 PS_DASH 事例

#include <windows.h>
int main( void )
{
    HWND hwnd = ::GetDesktopWindow();
    HDC hdc = ::GetWindowDC(hwnd);

    // 红,间隔透明
    HPEN hpen1 = CreatePen( PS_DASH, 1, RGB(255,0,0) );
    HGDIOBJ hPrePen = SelectObject( hdc, hpen1 );
    int hPreMode = SetBkMode( hdc, TRANSPARENT );
    MoveToEx( hdc, 0,10, NULL );
    LineTo( hdc, 400, 10 );
    SelectObject( hdc, hPrePen );
    SetBkMode( hdc, hPreMode );
    DeleteObject( hpen1 );

    // 绿,间隔蓝
    HPEN hpen2 = CreatePen( PS_DASH, 1, RGB(0,255,0) );
    hPrePen = SelectObject( hdc, hpen2 );
    hPreMode = SetBkMode( hdc, OPAQUE );
    COLORREF hPreClr = SetBkColor( hdc, RGB(0,0,255) );
    MoveToEx( hdc, 400,10, NULL );
    LineTo( hdc, 800, 10 );
    SelectObject( hdc, hPrePen );
    SetBkMode( hdc, hPreMode );
    SetBkColor( hdc, hPreClr );
    DeleteObject( hpen2 );

    return 0;
}

周星星
判断char是否有符号

//  for gcc
//     -fsigned-char
//     -funsigned-char
//  for vc
//     default
//     /J

bool char_is_signed = ('\x80'<0);

#include <iostream>
using namespace std;

int main()
{
    if( char_is_signed )
        cout << "char == signed char" << endl;
    else
        cout << "char == unsigned char" << endl;
   
    system("pause");
}

周星星
获取汉字的首拼字母(没什么用)

char xxx_gb2312( unsigned long word )
{
    static const unsigned long areacode[] = {
                          0xB0A1, 0xB0C5, 0xB2C1, 0xB4EE, 0xB6EA, 0xB7A2, 0xB8C1 // a b c d e f g
                        , 0xB9FE, 0xBBF7, 0xBBF7, 0xBFA6, 0xC0AC, 0xC2E8, 0xC4C3 // h i j k l m n
                        , 0xC5B6, 0xC5BE, 0xC6DA,         0xC8BB, 0xC8F6, 0xCBFA // o p q   r s t
                        , 0xCDDA, 0xCDDA, 0xCDDA,         0xCEF4, 0xD1B9, 0xD4D1 // u v w   x y z
                        , 0xF7FF };

    if( word>=areacode[0] && word<areacode[26] && (word&0xFF)>0xA0 && (word&0xFF)<0xFF )
    {
        for( int i=0; i<26; ++i )
        {
            if( word>=areacode[i] && word<areacode[i+1] )
                return 'A'+i;
        }
    }
    return '?';
}

#include <string>
std::string GetChineseSpell( const char* ptext ) // for test
{
    std::string s;

    for( const unsigned char* p=(const unsigned char*)ptext; *p; )
    {
        if( *p>0xA0 )
        {
            s += xxx_gb2312( p[0]<<8 | p[1] );
            p += 2;
        }
        else
        {
            s += xxx_gb2312( p[0] );
            p += 1;
        }
    }

    return s;
}

#include <iostream>
using namespace std;

int main( void )
{
    cout << GetChineseSpell("获取汉字的首拼字母") << endl;

    return 0;
}

周星星
一些不常用的浮点函数

#include <assert.h>
void test01( void );
void test02( void );
int main()
{
    test01();
    test02();
}

#include <math.h>
void test01( void )
{
    // ceil 进一法求整
    //   eg: 2.5,3.0等的ceil应当是3.0
    assert( ceil(2.5)==3.0 );
    assert( ceil(3.0)==3.0 );
    // floor 去尾法求整
    //   eg: 2.5,2.0等的floor应当是2.0
    assert( floor(2.5)==2.0 );
    assert( floor(2.0)==2.0 );

    // fmod 模除
    //   eg: 5.0%3.0应当是2.0
    assert( fmod(5.0,3.0)==2.0 );

    // modf 分解成整数和小数
    //   eg: 2.5分解为2.0和0.5
    double integer_portion;
    assert( modf(2.5,&integer_portion)==0.5 );
    assert( integer_portion==2.0 );

    // hypot 直角三角形斜边
    //   eg: 3.0和4.0对应的直角三角形斜边长为5.0
    assert( hypot(3.0,4.0)==5.0 );
}

#include <stdlib.h>
void test02( void )
{
    // rotl/lrotl 循环左移, rotr/lrotr 循环右移
    //   eg: 0x12345678循环左移4位后当是 0x23456781
    assert( _lrotl(0x12345678UL,4)==0x23456781UL );
}

周星星
求n阶乘的位数

#include <stdio.h>
#include <math.h>
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif

int main()
{
    // 输入
    double n = 10;
    // 计算
    double dl = 1;
    if( n > 1 )
        dl = ceil( (n*log(n)-n+log(2*n*M_PI)/2)/log(10.0) );
    // 输出
    printf( "%.0lf\n", dl );
}

周星星
显示jpg图像

HANDLE hfile = ::CreateFile( _T("F:\\1.jpg"), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, 0 );
if( INVALID_HANDLE_VALUE != hfile )
{
    LARGE_INTEGER fsize;
    if( GetFileSizeEx(hfile,(PLARGE_INTEGER)&fsize) && fsize.HighPart==0 )
    {
        HGLOBAL hGlobal = ::GlobalAlloc(GMEM_MOVEABLE,fsize.LowPart);
        if( NULL != hGlobal )
        {
            LPVOID pData = ::GlobalLock(hGlobal);
            if( NULL != pData )
            {
                DWORD nRead;
                BOOL frf = ::ReadFile( hfile, pData, fsize.LowPart, &nRead, 0 );
                ::GlobalUnlock(hGlobal);
                if( frf && fsize.LowPart==nRead )
                {
                    IStream* pStm;
                    if( SUCCEEDED( CreateStreamOnHGlobal(hGlobal,TRUE,&pStm) ) )
                    {
                        IPicture* pPic;
                        if( SUCCEEDED( OleLoadPicture(pStm,fsize.LowPart,TRUE,IID_IPicture,(LPVOID*)&pPic) ) )
                        {
                            OLE_XSIZE_HIMETRIC hmWidth;
                            OLE_YSIZE_HIMETRIC hmHeight;
                            pPic->get_Width( &hmWidth );
                            pPic->get_Height( &hmHeight );

                            CPaintDC dc(this);
                            double fX = (double)dc.GetDeviceCaps(HORZRES)*(double)hmWidth /((double)dc.GetDeviceCaps(HORZSIZE)*100.0);
                            double fY = (double)dc.GetDeviceCaps(VERTRES)*(double)hmHeight/((double)dc.GetDeviceCaps(VERTSIZE)*100.0);

                            pPic->Render( dc, 0, 0, (DWORD)fX, (DWORD)fY, 0, hmHeight, hmWidth, -hmHeight, NULL );
                        }
                    }
                }
            }
        }
    }
    CloseHandle( hfile );
}

周星星
[zt] typelist

struct NullType;
template <typename T0 = NullType, typename T1 = NullType, typename T2 = NullType,
          typename T3 = NullType, typename T4 = NullType, typename T5 = NullType>
struct typelist
{
    typedef T0 Head;
    typedef typelist<T1, T2, T3, T4, T5> Tail;
    enum { length = 1 + Tail::length };
};
template <>
struct typelist<NullType, NullType, NullType, NullType, NullType, NullType>
{
    enum { length = 0 };
};

template <typename TL, int n, bool OutOfRange = (n >= TL::length)>
struct type_at
{
    typedef typename type_at<typename TL::Tail, n-1>::type type;
};
template <typename TL>
struct type_at<TL, 0, false>
{
    typedef typename TL::Head type;
};
template <typename TL, int n>
struct type_at<TL, n, true>
{
};

template <typename T, typename U>
struct is_same_type
{
    enum { value = false };
};
template <typename T>
struct is_same_type<T, T>
{
    enum { value = true };
};

template <typename TL, typename T, int count = -1, bool equalsHead =
          is_same_type<typename TL::Head, T>::value>
struct index_of
{
    enum { value = 1 + index_of<typename TL::Tail, T, count-1>::value };
};
template <typename TL, typename T, int count>
struct index_of<TL, T, count, true>
{
    enum { value = 0 };
};
template <typename T, typename U, int count>
struct index_of<typelist<T>, U, count, false>
{
    enum { value = count };
};

/*
template <typename T, typename U, bool greaterThan = (sizeof(T) >= sizeof(U))>
struct type_selector
{
    typedef T type;
};
template <typename T, typename U>
struct type_selector<T, U, false>
{
    typedef U type;
};
template <typename TL>
struct largest_type
{
    typedef typename type_selector<typename TL::Head, typename largest_type<typename
            TL::Tail>::type>::type type;
};
template <typename T>
struct largest_type<typelist<T> >
{
    typedef T type;
};
*/

#include <iostream>
using namespace std;
int main()
{
    typedef typelist<int, float, double, char> types;

    cout << types::length << endl; // 共4个元素

    type_at<types,1>::type a = 1.1f; // 等同于 float a = 1.1f;

    cout << index_of<types,float>::value << endl; // float是types的第1个元素

    cout << index_of<types,unsigned>::value << endl; // 返回-1, unsigned不是types的元素
}

周星星
简单时间函数

#include <time.h>
#include <stdio.h>

void printtime( const struct tm* ptm )
{
    printf( "%04d年%02d月%02d日 %02d时%02d分%02d秒\n"
        , ptm->tm_year+1900, ptm->tm_mon+1, ptm->tm_mday
        , ptm->tm_hour, ptm->tm_min, ptm->tm_sec );
    printf( "本年第%03d天,星期%01d\n"
        , ptm->tm_yday+1, ptm->tm_wday );
}

int main( void )
{
    time_t t1 = time( 0 );
    struct tm* tm1 = localtime( &t1 ); // gmtime
    if( tm1 )
    {
        printtime( tm1 );
    }

    printf( "\n" );

    const int year = 2008;
    const int mon  = 10;
    const int day  = 1;
    const int hour = 0;
    const int min  = 0;
    const int sec  = 0;
    struct tm tm2 = { sec,min,hour, day,mon-1,year-1900, 0,0,0 };
    time_t t2 = mktime( &tm2 );
    if( t2 != -1 )
    {
        struct tm* tm2 = localtime( &t2 );
        printtime( tm2 );
    }

    return 0;
}

周星星
SHBrowseForFolder 用法事例

 

#include <iostream>
#include 
<string>
#define _WIN32_WINNT 0x0500
#include 
<windows.h>
#include 
<shlobj.h>
//Import library shell32.lib
using namespace std;

static int CALLBACK BffCallBack( HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData )
{
    
switch( uMsg )
    
{
    
case BFFM_INITIALIZED:
        SendMessageA(hwnd, BFFM_SETSELECTION, TRUE, lpData); 
// 这里有一个bug,如果是工程设置中的字符集为unicode,lpData必须是unicode,SendMessageA/SendMessageW并无效果
        break;
    
case BFFM_SELCHANGED:
        
{
            
//char szDir[MAX_PATH*2];
            
//BOOL bRet = SHGetPathFromIDListA( (LPITEMIDLIST)lParam, szDir );
            
//if( bRet )
            
//{
            
//    SHFILEINFOA sfi;
            
//    SHGetFileInfo( (LPCSTR)lParam, 0, &sfi, sizeof(sfi), SHGFI_PIDL|SHGFI_ATTRIBUTES );
            
//    if (sfi.dwAttributes & SFGAO_LINK)
            
//    {
            
//        SendMessageA( hwnd, BFFM_ENABLEOK, 0, FALSE );
            
//    }
            
//}
        }

        
break;
    
case BFFM_VALIDATEFAILED:
        
break;
    }


    
return 0;
}


int main()
{
    LPITEMIDLIST pidlRoot 
= NULL;
    
{
        SHGetSpecialFolderLocation( NULL, CSIDL_DRIVES, 
&pidlRoot );

        
//IShellFolder* psfRoot = NULL;
        
//SHGetDesktopFolder( &psfRoot );
        
//psfRoot->ParseDisplayName( NULL, NULL, L"D:\", NULL, &pidlRoot, NULL );
        
//psfRoot->Release();
    }

    
    
char DisplayName[MAX_PATH*2];
    BROWSEINFOA bi 
= { ::GetConsoleWindow(), pidlRoot, DisplayName, NULL, BIF_RETURNONLYFSDIRS, &BffCallBack, (LPARAM)"D:\"0 };
    LPITEMIDLIST pidl 
= SHBrowseForFolderA(&bi);
    
if (pidl)
    
{
        
char szBuffer[MAX_PATH*2];
        
if (SHGetPathFromIDListA(pidl, szBuffer))
        
{
            cout 
<< szBuffer << endl;
        }

        CoTaskMemFree( pidl );
    }

    CoTaskMemFree( pidlRoot );

    
return 0;
}
周星星
执行控制台命令,并获得其输出

#include <stdio.h>
#include <io.h>
#include <string>
int foo( const char* command, std::string& out )
{
    FILE* fpipe = _popen( command, "r" );
    if( !fpipe )
        return false;

    int fd = _fileno( fpipe );

    //if( fstat(fd,&pipestat) != 0 ) return false;.
    char buf[1024];
    out.clear();
    for( int nbr; (nbr=_read(fd,buf,_countof(buf)))>0; )
    {
        out += std::string( buf, nbr );
    }

    // _cwait
    int wstatus = _pclose( fpipe );

    if( wstatus!=-1 && (wstatus&255)==0 )
    {
        switch( (unsigned int)(wstatus) >> 8 )
        {
        case 126: // subsidiary program `%s' not executable
            return 1;
        case 127: // subsidiary program `%s' not found
            return 2;
        }
    }
    if( wstatus==-1 || !( (wstatus&255)==0 && ((unsigned int)(wstatus)>>8)<2 ) )
        return 3; // subsidiary program `%s' failed

    return 0;
}

#include <iostream>
using namespace std;
int main()
{
    string out;
    int r = foo( "dir c:", out );
    switch( r )
    {
    case 0:
        cout << out << endl;
        break;
    case 1:
        cout << "subsidiary program not executable." << endl;
        break;
    case 2:
        cout << "subsidiary program not found." << endl;
        break;
    case 3:
        cout << "subsidiary program failed." << endl;
        break;
    }

    return 0;
}

周星星
纪念刘和珍君
纪念刘和珍君

但段政府就有令,说她们是“暴徒”!
但接着就有流言,说她们是受人利用的。

       ————鲁迅
周星星
马丁-路德-金
在德国,
起初他们追杀共产主义者,
我没有说话,
因为我不是共产主义者;

接着他们追杀犹太人,
我没有说话,
因为我不是犹太人;

后来他们追杀工会成员,
我没有说话,
因为我不是工会成员;

此后,他们追杀天主教徒,
我没有说话,
因为我是新教教徒;

最后,他们奔我而来,
却再也没有人站起来为我说话了。
周星星
判断strtoull是否溢出,errno=0是必要的

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

int main()
{
    char* endptr;
    unsigned long long r;
   
    errno=0; r = strtoull( "1844674407370955161500000", &endptr, 10 );
    if( errno == ERANGE )
        printf( "%s\n", "error range" );
    else
        printf( "%I64u\n", r );
   
    errno=0; r = strtoull( "18446744073709551615", &endptr, 10 );
    if( errno == ERANGE )
        printf( "%s\n", "error range" );
    else
        printf( "%I64u\n", r );
   
    return 0;
}

周星星
求M数中取N数的排列组合

#include <cstddef>
bool init( size_t num, size_t pow, size_t loop[] )
{
    if( num > pow ) return false;

    for( size_t i=0; i<num; ++i )
        loop[i] = i;
    return true;
}
bool next( size_t num, size_t pow, size_t loop[] )
{
    size_t index = num;
    for( ; index!=0; --index )
    {
        if( loop[index-1]+1 < pow+index-num )
        {
            ++loop[index-1];
            break;
        }
    }
    if( index == 0 ) return false;

    for( ; index<num; ++index )
    {
        loop[index] = loop[index-1] + 1;
    }
    return true;
}

#include <iostream>
using namespace std;
int main()
{
    const size_t N = 3;
    const size_t M = 5;

    size_t loop[N];
    for( bool b=init(N,M,loop); b; b=next(N,M,loop) )
    {
        for( size_t i=0; i<N; ++i )
            cout << loop[i];
        cout << '\n';
    }
    cout << endl;

    return 0;
}

输出
012
013
014
023
024
034
123
124
134
234

周星星
Intel之CMOV等价指令

CMOVA/CMOVNBE 高于(CF=0 and ZF=0)
CMOVAE/CMOVNB 高于等于(CF=0)          == CMOVNC 无进位(CF=0)
CMOVB/CMOVNAE 低于(CF=1)              == CMOVC  有进位(CF=1)
CMOVBE/CMOVNA 低于等于(CF=1 or ZF=1)

CMOVG/CMOVNLE 大于(ZF=0 and SF=OF)
CMOVGE/CMOVNL 大于等于(SF=OF)
CMOVL/CMOVNGE 小于(SF<>OF)
CMOVLE/CMOVNG 小于等于(ZF=1 or SF<>OF)

CMOVE  等于(ZF=1)                     == CMOVZ  为零(ZF=1)
CMOVNE 不等于(ZF=0)                   == CMOVNZ 非零(ZF=0)

CMOVO  溢出(OF=1)
CMOVNO 无溢出(OF=0)

CMOVP/CMOVPE  偶数(PF=1)
CMOVNP/CMOVPO 非偶数(PF=0)

CMOVS  负数(SF=1)
CMOVNS 非负数(SF=0)

周星星
杨辉三角(随便写的,估计有更好的写法)
#include <iostream>
using namespace std;

// 杨辉三角
// 1
// 1 1
// 1 2 1
// 1 3 3 1
// 1 4 6 4 1
// 1 5 10 10 5 1
// 1 6 15 20 15 6 1
// 1 7 21 35 35 21 7 1
// 1 8 28 56 70 56 28 8 1
// 1 9 36 84 126 126 84 36 9 1

int main()
{
    const size_t N = 10; // 行数

    unsigned line[N] = { 1 };
    for( size_t i=0; i<N; ++i )
    {
        for( size_t j=i; j>0; --j ) // 计算出第i行
            line[j] += line[j-1];

        for( size_t m=0; m<i+1; ++m ) // 输出第i行
            cout << ' ' << line[m];
        cout << endl;
    }

    return 0;
}
周星星
lexical_cast
template<typename Target, typename Source>
Target lexical_cast(Source arg) {
    std::stringstream interpreter;
    Target result;
    if( !(interpreter<<arg) || !(interpreter>>result) || !(interpreter>>std::ws).eof() )
        throw bad_lexical_cast();
    return result;
}
周星星
将指定控件的字体加粗
HFONT hFont = (HFONT)::SendMessage( m_hName, WM_GETFONT, 0, 0 );
if(hFont==0) hFont=(HFONT)::GetStockObject(SYSTEM_FONT);
LOGFONT dtLogFont;
::GetObject( hFont, sizeof(dtLogFont), &dtLogFont );
dtLogFont.lfWeight = FW_BOLD;
hFont = ::CreateFontIndirect(&dtLogFont);
::SendMessage( m_hName, WM_SETFONT, (WPARAM)hFont, MAKELONG(TRUE,0) );
周星星
将一堆数分成a和b两等份,且使得 a的和 与 b的和 之差最小

// 暴力求解法(效率不行)
//假设数据为 1 2 3 3 4 5
//那么只有以下几种分法:
//1 2 3 | 3 4 5
//1 2 4 | 3 3 5
//1 2 5 | 3 3 4
//1 3 3 | 2 4 5
//1 3 4 | 2 3 5
//1 3 5 | 2 3 4
//1 4 5 | 2 3 3
//分别计算每一种分法的差值,取最小者。

#include <cassert>
#include <algorithm>

// 最差情况下(无重复数字),时间复杂度是O( n! / (n/2)! / (n/2)! / 2 )
// 假设n为6,则时间复杂度是O( (6*5*4)/(3*2*1)/2 ) = 10
bool nextpermutation( int buf[], size_t n )
{
    assert( n!=0 && n%2==0 );

    for( size_t i=n/2-1; i!=0; --i ) // 之所以不是 i!=-1,是因为第一个数放在A堆中和放在B堆中一样,因此假定放在A堆中,去掉一半的重复
    {
        int* p = std::upper_bound( buf+i+1, buf+n, buf[i] );
        if( p+(n/2-i) > buf+n )
        {
            std::sort( buf+i, buf+n );
            continue;
        }
        std::swap_ranges( p, p+(n/2-i), buf+i );
        if( i != n/2-1 )
            std::sort( buf+n/2, buf+n );
        return true;
    }
    return false;
}

#include <numeric>

int foo( int buf[], size_t n, int out[] )
{
    assert( n!=0 && n%2==0 );

    int sum = std::accumulate( buf+0, buf+n, 0 );
    std::sort( buf+0, buf+n );
    int diff = ::abs( 2*std::accumulate(buf+0,buf+n/2,0) - sum );
    std::copy( buf+0, buf+n, out );
    if( diff == 0 ) return 0;
    while( nextpermutation(buf,n) )
    {
        int diff2 = ::abs( 2*std::accumulate(buf+0,buf+n/2,0) - sum );
        if( diff2 < diff )
        {
            diff = diff2;
            std::copy( buf+0, buf+n, out );
            if( diff == 0 ) return 0;
        }
    }

    return diff;
}


#include <iostream>
#include <iterator>
using namespace std;

//void test( int buf[], size_t n )
//{
//    assert( n!=0 && n%2==0 );
//
//    std::ostream_iterator<int> oitor( std::cout, " " );
//    std::sort( buf+0, buf+n );
//    std::copy( buf+0, buf+n/2, oitor ); std::cout << ", ";
//    std::copy( buf+n/2, buf+n, oitor ); std::cout << '\n';
//    while( nextpermutation(buf,n) )
//    {
//        std::copy( buf+0, buf+n/2, oitor ); std::cout << ", ";
//        std::copy( buf+n/2, buf+n, oitor ); std::cout << '\n';
//    }
//    cout << flush;
//}

int main()
{
    // input
    int buf[] = { 1, 2, 3, 3, 4, 5 };
    //int buf[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    //int buf[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
    //int buf[] = { 1, 3, 7, 2, 3, 4 };
    //int buf[] = { 11, 7, 6, 10, 9, 1 };

    // pre deal
    const size_t n = sizeof(buf)/sizeof(buf[0]);

    // test
    //test( buf, n );

    // foo
    int out[n];
    int diff = foo( buf, n, out );

    // output
    ostream_iterator<int> oitor( cout, " " );
    cout << '\n';
    cout << "A: "; std::copy( out+0, out+n/2, oitor ); cout << '\n';
    cout << "B: "; std::copy( out+n/2, out+n, oitor ); cout << '\n';
    cout << "different = " << diff << endl;

    return 0;
}


// ----------------------------
// [woshiyun]的算法: 将a中的每个元素和b中的每个元素比较,如果交换可以使得差值变小则交换。若无可交换者,结束。
// [bruceteen]存疑: 会不会存在“交换每一个数都无法使得差值变小,但同时交换一组数据可以使得差值变小”的情况呢?

#include <cassert>
#include <numeric>

int foo( int a[], int b[], size_t n )
{
    int diff = std::accumulate( a, a+n, -std::accumulate(b,b+n,0) );
    if( diff == 0 ) return 0;

    for( bool bswapped=true; bswapped; )
    {
        bswapped = false;

        for( size_t i=0; i<n; ++i )
        {
            for( size_t j=0; j<n; ++j )
            {
                int& x = a[i];
                int& y = b[j];

                if( ( diff>0 && x>y && x-y<diff ) || ( diff<0 && x<y && x-y>diff ) )
                {
                    diff -= 2*( x - y );
                    std::swap( x, y );
                    if( diff == 0 ) return 0;
                    bswapped = true;
                }
            }
        }
    }

    return diff;
}

#include <iostream>
#include <iterator>
using namespace std;

int main()
{
    int a[] = { 2, 8, 20, 80 };
    int b[] = { 1, 4, 10, 40 };

    const size_t n = sizeof(a)/sizeof(a[0]);
    int diff = foo( a, b, n );

    ostream_iterator<int> oitor( cout, " " );
    cout << '\n';
    cout << "A: "; std::copy( a, a+n, oitor ); cout << '\n';
    cout << "B: "; std::copy( b, b+n, oitor ); cout << '\n';
    cout << "different = " << diff << endl;
}

周星星
在文件浏览器中打开选择指定文件
例如:
explorer.exe /n, /select, C:\WINDOWS\system32\drivers\etc\hosts
将打开浏览到 C:\WINDOWS\system32\drivers\etc 目录,并 选择hosts文件。
/n 在C:\WINDOWS\system32\drivers\etc已经被打开的情况下,依然打开一个新浏览器。
周星星
将控制台的关闭按钮变灰

#define _WIN32_WINNT  0x0501 // xp
#include <windows.h>
#include <conio.h>

int main()
{
    HWND hwnd = GetConsoleWindow();
    HMENU hmenu = GetSystemMenu( hwnd, FALSE );
    RemoveMenu( hmenu, SC_CLOSE, MF_BYCOMMAND ); // 删除控制台的Close菜单项

    _getch();
    return 0;
}

周星星
uintptr_t 和 ptrdiff_t
它们包含在<cstddef>(C++)和<stddef.h>(C)中

当将指针类型转化为整型时,整型应当使用uintptr_t类型
保存两个指针相减的值时,这个值的类型当使用ptrdiff_t类型
周星星
BOM ( byte-order mark )
Bytes Encoding Form
00 00 FE FF UTF-32, big-endian
FF FE 00 00 UTF-32, little-endian
FE FF UTF-16, big-endian
FF FE UTF-16, little-endian
EF BB BF UTF-8
周星星
并集 交集 差集 对称差集

#include <iostream>
#include <algorithm>
#include <vector>
#include <iterator>
using namespace std;

int main()
{
    int a[] = { 1, 1, 2, 2, 2 };
    int b[] = { 2, 2, 3, 3 };
    // assert( a, b 是有序的 )

    // 并集 1 1 2 2 2 3 3
    {
        int c[10];
        int* p = set_union( a+0, a+_countof(a), b+0, b+_countof(b), c+0 );
        copy( c+0, p, ostream_iterator<int>(cout," ") ); cout<<endl;
    }
    // 交集 2 2
    {
        vector<int> c;
        set_intersection( a+0, a+_countof(a), b+0, b+_countof(b), back_inserter(c) );
        copy( c.begin(), c.end(), ostream_iterator<int>(cout," ") ); cout<<endl;
    }
    // 差集 1 1 2
    {
        vector<int> c;
        set_difference( a+0, a+_countof(a), b+0, b+_countof(b), back_inserter(c) );
        copy( c.begin(), c.end(), ostream_iterator<int>(cout," ") ); cout<<endl;
    }
    // 对称差集 1 1 2 3 3
    {
        vector<int> c;
        set_symmetric_difference( a+0, a+_countof(a), b+0, b+_countof(b), back_inserter(c) );
        copy( c.begin(), c.end(), ostream_iterator<int>(cout," ") ); cout<<endl;
    }

    return 0;
}

周星星
lower_bound upper_bound 和 equal_range

#include <iostream>
#include <algorithm>
#include <iterator>
using namespace std;

int main()
{
    int a[] = { 1,1,2,2,3,3 };

    // 返回第一个大于或等于指定值的迭代器
    int* p1 = lower_bound( a+0, a+_countof(a), 2 );
    // 返回第一个大于指定值的迭代器
    int* p2 = upper_bound( a+0, a+_countof(a), 2 );
    copy( p1, p2, ostream_iterator<int>(cout," ") ); cout<<endl; // 输出 2 2

    // 返回等于2的区间
    pair<int*,int*> ps = equal_range( a+0, a+_countof(a), 2 );
    copy( ps.first, ps.second, ostream_iterator<int>(cout," ") ); cout<<endl; // 输出 2 2

    return 0;
}

周星星
equal_range返回一个区间的取巧做法

#include <iostream>
#include <algorithm>
#include <iterator>
#include <functional>
using namespace std;

struct greaterequal2_and_lessequal3 : binary_function<int, int, bool>
{
    bool operator()( const int& lhs, const int& rhs ) const
    {
        return ( lhs<2 && rhs>=2 ) || ( lhs<=3 && rhs>3 );
    }
};

int main()
{
    int a[] = { 1,1,2,2,3,3,4,4 };

    // 返回大于等于2,小于等于3的区间
    pair<int*,int*> ps = equal_range( a+0, a+_countof(a), 2, greaterequal2_and_lessequal3() ); // 这里的2可以随便填一个大于等于2小于等于3的数

    copy( ps.first, ps.second, ostream_iterator<int>(cout," ") ); cout<<endl; // 输出 2 2 3 3
    return 0;
}

周星星
[oshj]说“隐式转换不参与模板实参的推导”

template<typename T> struct A
{
};

struct foo
{
    operator A<int>() const
    {
        return A<int>();
    }
};

template<typename T> void test1( T )
{
}
template<typename T> void test2( A<T> )
{
}

int main()
{
    foo a;
    test1( a );
    test2( a ); // failed
}

周星星
特殊文件的创建和删除

特殊文件,比如con等,比如空格结尾的文件名,用
md con\
md "test \"
即用斜杠结尾,或者用 md \\?\"全路径\test "

点结尾的文件名,用“.\”结尾,比如创建3个点为名称的目录,那就用4个点,如
md "....\" 或 md \\?\"全路径\..." (注意,这里只需要3个点)

删除它们可以用同样的方法,或用 dir /x 取得8.3短格式后用短名称删除

周星星
已知直线1上两点(x1,y1),(x2,y2) 和 直线2上两点(x3,y3),(x4,y4),求两直线交点坐标

    (x1y2-x2y1)(x3-x4) - (x3y4-x4y3)(x1-x2)
x = ---------------------------------------
        (x1-x2)(y3-y4) - (x3-x4)(y1-y2)


    (x1y2-x2y1)(y3-y4) - (x3y4-x4y3)(y1-y2)
y = ---------------------------------------
        (x1-x2)(y3-y4) - (x3-x4)(y1-y2)

周星星
遍历TreeView中的Item

HTREEITEM TreeView_GetLastEnumItem( HWND hTree, HTREEITEM hCurrent )
{
    HTREEITEM hItem = hCurrent;
    for( HTREEITEM hChildItem=hItem; hChildItem=TreeView_GetChild(hTree,hChildItem), hChildItem!=NULL; hItem=hChildItem )
    {
        for( HTREEITEM hNextChildItem=hChildItem; hNextChildItem=TreeView_GetNextSibling(hTree,hNextChildItem), hNextChildItem!=NULL; hChildItem=hNextChildItem );
    }
    return hItem;
}
HTREEITEM TreeView_GetPrevEnumItem( HWND hTree, HTREEITEM hCurrent )
{
    HTREEITEM hPreSibling = TreeView_GetPrevSibling( hTree, hCurrent );
    if( hPreSibling != NULL )
    {
        HTREEITEM hItem = hPreSibling;
        for( HTREEITEM hChildItem=hItem; hChildItem=TreeView_GetChild(hTree,hChildItem), hChildItem!=NULL; hItem=hChildItem )
        {
            for( HTREEITEM hNextChildItem=hChildItem; hNextChildItem=TreeView_GetNextSibling(hTree,hNextChildItem), hNextChildItem!=NULL; hChildItem=hNextChildItem );
        }
        return hItem;
    }
    return TreeView_GetParent( hTree, hCurrent );
}
HTREEITEM TreeView_GetNextEnumItem( HWND hTree, HTREEITEM hCurrent )
{
    HTREEITEM hChildItem = TreeView_GetChild( hTree, hCurrent );
    if( hChildItem != NULL )
        return hChildItem;

    for( HTREEITEM hParentItem=hCurrent; hParentItem!=NULL; hParentItem=TreeView_GetParent(hTree,hParentItem) )
    {
        HTREEITEM hUncleItem = TreeView_GetNextSibling( hTree, hParentItem );
        if( hUncleItem != NULL )
            return hUncleItem;
    }

    return NULL;
}

周星星
找出一个整数数组相邻子数组相加的最大值 [mysoft]
#include <stdio.h>

void foo( int buf[], int n )
{
    
int a=0, b=0, sum=0// a为起始下标,b为连续长度,sum为和
    int a1=0, b1=0, sum1=0// 暂时的可能
    forint i=0; i<n; ++i )
    
{
        sum1 
+= buf[i]; // 接纳此元素后的和
        if( sum1 > 0 ) // 只要大于零,将来总是有可能变得更大的。有希望就要保留!
        {
            
++b1;
        }

        
else // 负数将来也有可能变得更大呀?我靠,那我还不如直接从0开始
        {
            a1 
= i+1;
            b1 
= 0;
            sum1 
= 0;
        }


        
if( sum1 > sum ) // 如果“暂时的可能”最优,当然它就成“正式的”啦
        {
            a 
= a1;
            b 
= b1;
            sum 
= sum1;
        }

    }


    
if( b != 0 )
        printf( 
"Sum(%d,%d)=%d ", a, a+b-1, sum );
    
else
        printf( 
"%s ""全TMD没个正数,当然是零个连续和最大呀!" );
}


int main()
{
    
int buf[] = 2,3,-6,3,4,3,-2,5,2,-3 }// Sum(3,8)=15
    foo( buf, sizeof(buf)/sizeof(buf[0]) );

    
return 0;
}


整个算法就像一个蠕虫,头部每次向前爬一格,如果总和大于0的话就一直爬;如果小于0,那把尾巴缩到头部,头部继续爬
上述就是一个遍历的过程,现在只要将这过程中的最大和记录下来就行了
周星星
接上贴,求不连续子项和最大值

算法是从网上看到的,非常精妙,向作者致敬,我转载一下
int foo( int buf[], int n )
{
    int s1 = 0;
    int s2 = buf[0];
    for( int i=1; i<n; ++i )
    {
        if( s1 <= 0 )
            s1 = 0;

        int tmp = s2;
        if( buf[i]+s1 > s2 )
            s2 = buf[i]+s1;
        s1 = tmp;
    }
    return s2;
}

 

周星星
求1到n的异或
unsigned foo( unsigned n ) // 1^2^3^…^n
{
    char r[] = { n, 1, n+1, 0 };
    return r[n%4];
}
周星星
判断int32_t中有没有一个字节值为0
if( ( (~a^(a+0x7efefeff)) & ~0x7efefeff ) != 0 ) 有
周星星
最简单的控制台中定点输出

#include <windows.h>
#include <time.h>
#include <stdio.h>

void printtime( const struct tm* ptm )
{
    printf( "%04d年%02d月%02d日 %02d时%02d分%02d秒\n"
        , ptm->tm_year+1900, ptm->tm_mon+1, ptm->tm_mday
        , ptm->tm_hour, ptm->tm_min, ptm->tm_sec );
    printf( "本年第%03d天,星期%01d\n"
        , ptm->tm_yday+1, ptm->tm_wday );
}

int main( void )
{
    HANDLE hOutput = ::GetStdHandle(STD_OUTPUT_HANDLE);

    printf( "%s", "当前时间: " );
    CONSOLE_SCREEN_BUFFER_INFO screen_info;
    ::GetConsoleScreenBufferInfo( hOutput, &screen_info );

    for( time_t t1=0,t2; t2=time(0); Sleep(100) )
    {
        if(t2==t1) continue;
        t1 = t2;

        struct tm* tmo = localtime( &t1 );
        ::SetConsoleCursorPosition(hOutput,screen_info.dwCursorPosition);
        printtime( tmo );
    }

    return 0;
}

周星星
一个带有环的单链表,设计算法查找这个环的起点


struct Node
{
    int val;
    struct Node* next;

    Node( int v ) : val(v), next(0)
    {
    }
};

Node* foo( Node* head )
{
    // p1以每次一个节点的速度前进,p2每次2个,那么这两个指针一定在链表的环中相遇
    Node* p1 = head;
    for( Node* p2=head; p1=p1->next, p2=p2->next->next, p1!=p2; );

    // 相遇点距离环的起点 和 链表头距离离环的起点 相等
    Node* p3 = head;
    for( ; p3!=p1; p3=p3->next, p1=p1->next );

    return p3;
}

#include <iostream>
int main()
{
    // 构建一个单链表 0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 ->8 -> 9 -> (4)
    Node* head = 0;
    {
        Node** p = &head;
        Node* tmp = 0;
        for( int i=0; i<=9; ++i )
        {
            *p = new Node(i);
            if( i == 4 )
                tmp = *p;
            p = &((*p)->next);
        }
        *p = tmp;
    }

    // 测试
    Node* p = foo( head );
    std::cout << p->val << std::endl;

    return 0;
}

周星星
使用默认用户名和密码自动登陆XP
1. 在控制面板中的“用户账户”中取消“要使用本机,用户必须输入用户名和密码”
假如没有“要使用本机,用户必须输入用户名和密码”,则在注册表HKEY_LOCAL_MACHIN\SOFTWARE\MicroSoft\Windows NT\CurrentVersion\Winlogon中修改AutoAdminLogon为1(REG_SZ),重新打开“用户账户”。
2. 点应用,输入用户名和密码
如果是域用户,这在用户名前加上“域名\”,即“域名\用户名”
周星星
最大公约数
int gcd( int a, int b )
{
    if(a<0) a = -a;
    if(b<0) b = -b;
    if(a==0) return b;
    if(b==0) return a;
    if(a<b) { int c=a; a=b; b=c; }

    for( int c; (c=a%b)!=0; a=b,b=c );
    return b;
}
1 2 下一页共2页  到第

发表评论
切换编辑模式