查看完整版本: 讀取中文字
頁: [1] 2

a78798302 發表於 2016-3-31 07:14 PM

讀取中文字

老師出的回家作業其中一小部分,需要使用者輸入中文,然後依照輸入的中文字進行不同的動作,但是不能按下Enter(也不能有跳行的動作)
(ex:輸入"早",然後自動列印出"安")

其中輸入我想到了scanf、getchar、getche、getch,而不能按下Enter則只剩下getche和getch,不能有跳行的動作只有getch能達成我想要的需求...

但是getch一次只讀入1 byte,但是中文卻要2 bytes,而getch又沒有緩衝區,一次讀1 byte的話會造成輸入中文後顯示亂碼{:51:}

想請問各位大大,要怎麼做呢?{:38:}
...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div><div></div>

snowflying 發表於 2016-3-31 08:33 PM

本帖最後由 snowflying 於 2016-3-31 08:41 PM 編輯

看看這個可不可以
#include <conio.h>
#include <stdio.h>
#include <string.h>
#define print printf

int main()
{
    char arr = {};
   
    while(1)
    {
        arr = getch();
        
        if(arr & 0x80)
        {
            arr = getch();
            print("%s" , arr);
            
            if(!strcmp(arr , "早"))
                print("安");
            if(!strcmp(arr , "你"))
                print("好");
        }
        else
            putchar(arr);
    }
    return 0;
}

...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div>

a78798302 發表於 2016-3-31 09:48 PM

snowflying 發表於 2016-3-31 08:33 PM static/image/common/back.gif
看看這個可不可以

不好意思,沒辦法.....
我輸入"早"沒有反應,若再輸入一次"早",反而跳出亂碼
(不知道和作業系統有沒有關係?我是Windows 10)

snowflying 發表於 2016-3-31 09:54 PM

本帖最後由 snowflying 於 2016-3-31 10:10 PM 編輯

a78798302 發表於 2016-3-31 09:48 PM static/image/common/back.gif
不好意思,沒辦法.....
我輸入"早"沒有反應,若再輸入一次"早",反而跳出亂碼
(不知道和作業系統有沒有關 ...
確定中文字為 2 bytes 嗎?
測試看看這個,順便看一剛開始輸出的數字是多少


#include <conio.h>
#include <stdio.h>
#include <string.h>
#define print printf

int main()
{
    const char str[] = "早";
    const int len = sizeof(str) - 1;
    char arr = {};
    int idx;
   
    print("%d\n" , len);
   
    while(1)
    {
        memset(arr , 0 , sizeof(arr));
        idx = 1;
        
        arr = getch();
        
        if(arr & 0x80)
        {
            while(idx < len)
                arr = getch();
               
            print("%s" , arr);
            
            if(!strcmp(arr , "早"))
                print("安");
            if(!strcmp(arr , "你"))
                print("好");
        }
        else
            putchar(arr);
    }
    return 0;
}



...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div>

a78798302 發表於 2016-3-31 10:30 PM

snowflying 發表於 2016-3-31 09:54 PM static/image/common/back.gif
確定中文字為 2 bytes 嗎?
測試看看這個,順便看一剛開始輸出的數字是多少



是2 bytes沒錯
這個新的程式碼還是和上個程式碼一樣的狀況..<br><br><br><br><br><div></div>

snowflying 發表於 2016-3-31 10:38 PM

a78798302 發表於 2016-3-31 10:30 PM static/image/common/back.gif
是2 bytes沒錯
這個新的程式碼還是和上個程式碼一樣的狀況..

我這邊測試是可以的
如果只用 scanf 和 print f ,並且按下 ENTER,中文字是可以正常輸出的?

那下面這個呢?
#include <stdio.h>
#include <string.h>
#include <windows.h>
#define print printf

int main()
{
        HANDLE console;
        DWORD mode;
        DWORD cnt;
        char buf = {};
       
        console = GetStdHandle(STD_INPUT_HANDLE);
        GetConsoleMode(console , &mode);
        SetConsoleMode(console , mode & ~ENABLE_LINE_INPUT);
       
        while(ReadConsole(console , buf , 7 , &cnt , NULL))
        {
                print("%s" , buf);

                if(!strcmp(buf , "早"))
                        print("%s" , "安");
                if(!strcmp(buf , "你"))
                        print("%s" , "好");
                       
                memset(buf , 0 , sizeof(buf));
        }
       
        return 0;
}
...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div>

a78798302 發表於 2016-3-31 11:36 PM

snowflying 發表於 2016-3-31 10:38 PM static/image/common/back.gif
我這邊測試是可以的
如果只用 scanf 和 print f ,並且按下 ENTER,中文字是可以正常輸出的?



感謝~
電腦已關機了,我明天再試試看~
我用scanf和printf也都可以正常列印出中文

您說您自己測試是可以,但我這邊不行,會不會是因為我電腦是Windows 10的關係?...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div>

snowflying 發表於 2016-3-31 11:48 PM

a78798302 發表於 2016-3-31 11:36 PM static/image/common/back.gif
感謝~
電腦已關機了,我明天再試試看~
我用scanf和printf也都可以正常列印出中文


不清楚,我沒有用過 Win10

你是用 Visual Studio? CodeBlocks? Dev-C++?
我這邊測試是用 Dev-C++ 5.11

明天可能要先測看看 6樓的程式碼
看結果如何再說
...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div>

a78798302 發表於 2016-4-1 08:18 AM

本帖最後由 a78798302 於 2016-4-1 08:33 AM 編輯

snowflying 發表於 2016-3-31 11:48 PM static/image/common/back.gif
不清楚,我沒有用過 Win10

你是用 Visual Studio? CodeBlocks? Dev-C++?

成功了!
真的很感謝您{:2:}
沒想到竟然要複雜到使用windows.h....@_@"
想請問一下 mode & ~ENABLE_LINE_INPUT 是什麼意思呢?

ReadConsole(console , tmp , 7, &cnt , NULL) 那個7的意思是陣列最後一個的意思嗎?

我用的是CodeBlocks 13.12


...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div>

snowflying 發表於 2016-4-1 02:39 PM

a78798302 發表於 2016-4-1 08:18 AM static/image/common/back.gif
成功了!
真的很感謝您
沒想到竟然要複雜到使用windows.h....@_@"


mode & ~ENABLE_LINE_INPUT 是關掉 ENABLE_LINE_INPUT
讓 ReadConsole 不需要等到換行就能讀值
7 是要讀的個數,但實際讀了多少,是存在 cnt 內

https://msdn.microsoft.com/zh-tw/library/windows/desktop/ms686033%28v=vs.85%29.aspx
...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div><br><br><br><br><br><div></div>

a78798302 發表於 2016-4-1 05:24 PM

snowflying 發表於 2016-4-1 02:39 PM static/image/common/back.gif
mode & ~ENABLE_LINE_INPUT 是關掉 ENABLE_LINE_INPUT
讓 ReadConsole 不需要等到換行就能讀值
7 是要讀 ...

不好意思再問一個問題...
這個程式碼要怎麼讓它知道使用者有按下ESC呢?
我知道ESC的ASCII是27,但是ESC按了程式根本就沒反應.....<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div>

snowflying 發表於 2016-4-2 04:57 AM

a78798302 發表於 2016-4-1 05:24 PM static/image/common/back.gif
不好意思再問一個問題...
這個程式碼要怎麼讓它知道使用者有按下ESC呢?
我知道ESC的ASCII是27,但是ESC ...

測看看能不能正常跑


#include <stdio.h>
#include <string.h>
#include <windows.h>
#define print printf

int main()
{
    HANDLE console;
    DWORD mode;
    DWORD cnt , cnt2;
    char buf = {};
    INPUT_RECORD rec;
   
    console = GetStdHandle(STD_INPUT_HANDLE);
    GetConsoleMode(console , &mode);
    SetConsoleMode(console , mode & ~ENABLE_LINE_INPUT);
   
    while(1)
    {
        if(ReadConsoleInput(console , rec , 8 , &cnt) )
        {
            if (rec.EventType != KEY_EVENT || !rec.Event.KeyEvent.bKeyDown)
                continue;
            
            if(cnt == 1 && rec.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE)
            {
                puts("ESC");
                break;
            }
            
            cnt2 = cnt;
            WriteConsoleInput(console , rec , cnt2 , &cnt);
            cnt2 = cnt;
            
            ReadConsole(console , buf , cnt2 , &cnt , NULL);
            print("%s" , buf);
   
            if(!strcmp(buf , "早"))
                print("%s" , "安");
            if(!strcmp(buf , "你"))
                print("%s" , "好");
               
            memset(buf , 0 , sizeof(buf));
        }
    }
   
    return 0;
}


...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div>

a78798302 發表於 2016-4-2 09:44 AM

snowflying 發表於 2016-4-2 04:57 AM static/image/common/back.gif
測看看能不能正常跑

謝謝回復>"<
雖然改成這樣後可以正常讀取到ESC,可是一旦輸入中文又變成了亂碼...Q_Q

snowflying 發表於 2016-4-2 11:15 AM

a78798302 發表於 2016-4-2 09:44 AM static/image/common/back.gif
謝謝回復>"<
雖然改成這樣後可以正常讀取到ESC,可是一旦輸入中文又變成了亂碼...Q_Q ...

這真是太神奇了,我改了一段時間,這邊測試也是正常的 ~"~

a78798302 發表於 2016-4-2 11:48 AM

snowflying 發表於 2016-4-2 11:15 AM static/image/common/back.gif
這真是太神奇了,我改了一段時間,這邊測試也是正常的 ~"~

看來就是Windows 10的關係了....~_~"<br><br><br><br><br><div></div>
頁: [1] 2