2015-11-03 120 views
0

我不知道這裏發生了什麼,雖然它很酷且奇怪的令人毛骨悚然,但這並不是我真正想到的。奇怪的文字界面打印

基本上;我試圖實現一個程序,在黑色界面上減慢文本類型。我正在使用SDL2和SDL2_TTF來完成這個任務,並且事情已經順利完成。

目前,我在其中鍵入「嘿;)」到黑屏,但這裏發生的事情: Interesting text.

忽略FPS計數器,這只是Nvidia的。

我真的不知道發生了什麼,我使用的字體是「Hack-Regular.ttf」。

走上代碼:

#include<iostream> 
#include<SDL.h> 
#include<string> 
#include<SDL_ttf.h> 


void handleEvents(SDL_Event e, bool* quit){ 
    while(SDL_PollEvent(&e) > 0){ 
     if(e.type == SDL_QUIT){ 
      *quit = true; 
     } 
    } 
} 

void render(SDL_Renderer* renderer, SDL_Texture* textToRender, SDL_Rect srcrect, SDL_Rect dstrect){ 
    SDL_RenderClear(renderer); 

    SDL_RenderCopy(renderer, textToRender, &srcrect, &dstrect); 

    SDL_RenderPresent(renderer); 
} 

void printToConsole(std::string message, char* text){ 
    for(int i = 0; i < message.length(); i++){ 
     *text = *text + message.at(i); 
     SDL_Delay(30); 
    } 
} 

void start(char text){ 
    printToConsole("Hey ;)", &text); 
} 

int main(int argc, char *argv[]) { 
    SDL_Init(SDL_INIT_EVERYTHING); 
    TTF_Init(); 
    SDL_Window* window = SDL_CreateWindow("Game", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 600, 600, SDL_RENDERER_ACCELERATED); 
    SDL_Renderer* renderer = SDL_CreateRenderer(window, 0, 0); 

    char text = 'asdf'; //This is the text that has been rendered. 
    bool quit = false; 
    SDL_Event e; 

    TTF_Font* font = TTF_OpenFont("Hack-Regular.ttf", 28); 
    SDL_Color color = {255, 255, 255}; 
    SDL_Surface* textSurface; 
    SDL_Texture* textTexture; 

    SDL_Rect srcrect; 
    SDL_Rect dstrect; 

    srcrect.x = 0; 
    srcrect.y = 0; 
    srcrect.w = 100; 
    srcrect.h = 32; 
    dstrect.x = 640/2; 
    dstrect.y = 480/2; 
    dstrect.w = 100; 
    dstrect.h = 32; 

    while(!quit){ 
     handleEvents(e, &quit); 
     render(renderer, textTexture, srcrect, dstrect); 

     start(text); 

     textSurface = TTF_RenderText_Solid(font, &text, color); 
     textTexture = SDL_CreateTextureFromSurface(renderer, textSurface); 
    } 

    SDL_DestroyWindow(window); 
    SDL_DestroyRenderer(renderer); 

    window = NULL; 
    renderer = NULL; 
    TTF_Quit(); 
    SDL_Quit(); 
    return 0; 
} 

我的道歉,如果是很難讀,我覺得沒必要使用多個類。

需要注意的是,「f」是'asdf'的最後一個字母我將文本定義爲最初,不知道爲什麼它從那裏開始。

+0

爲什麼'start()'採用'char'參數而不是'char *'?無論哪種方式,'printToConsole()'中的'&text'參數都不是很有意義。 – genpfault

+0

爲什麼'char text ='asdf''而不是'char * text =「asdf」'? – genpfault

回答

2

在下面的語句,定義佔用的存儲器1個字節的變量,並存儲在ASCII整數值102,又名「F」:

char text = 'asdf'; //This is the text that has been rendered. 

有幾個問題與上述語句:

  • 單個char變量只能存儲一個字符,一個字節的內存。您正在嘗試分配4.只有最後一個值保留。
  • 您正在嘗試使用單個字符,你的意思是使用'c-string'
  • 您對c字符串使用單引號語法。
  • 由於變量只存儲單個字節,所以在該單個值之後的下一個字節的內存未定義 - 它在程序中的其他位置的任意內存,可能是堆棧中接下來分配的任何值。
  • 如果您已經正確地聲明瞭該變量,稍後您將嘗試寫入只讀內存,因爲c-string文字通常會加載到只讀內存中。

您則該值傳遞給渲染程序,通過取變量的地址,並把它當作一個char*類型:

textSurface = TTF_RenderText_Solid(font, &text, color); 

然而,在C/C++,也被習慣使用char*存儲一個指向'c-string'的指針 - 也就是一個帶有最終空終止符的字符序列。在接受char*參數作爲c字符串的API中,您需要將指針傳遞給末尾具有空終止符的字符序列。

由於它希望傳遞的值是一個c字符串,因此它會盲目地從內存中讀取,直到它看到一個值爲0的字節爲止。由於它正在讀取爲該變量留出的內存末端只有一個字節),它會讀取任意內存,直到它幸運地找到某個地方的零 - 因此它顯示爲垃圾。

...

你如何解決這個問題?那麼,這取決於你將如何獲得你的絃樂。

隨着您提供的代碼,沒有真正的理由來分配自己的C字符串。如果您有string對象,則可以使用c_str()方法訪問char*兼容c字符串的緩衝區;只要你沒有修改string,返回的指針是有效的,並且由於返回的指針歸string所有,所以你不需要擔心清理它。

// Use the string class's implicit conversion from a c-string literal to 
// a `std::string` object. 
std::string text = "hello world"; 

... 

while(!quit){ 
    handleEvents(e, &quit); 
    render(renderer, textTexture, srcrect, dstrect); 

    // Note the lack of a call to the `start` method here. 

    textSurface = TTF_RenderText_Solid(font, text.c_str(), color); 
    textTexture = SDL_CreateTextureFromSurface(renderer, textSurface); 
} 

如果你想有引用語義 - 也就是說,有你在你的主聲明text變量,來傳遞讓你的程序的其他部分進行修改,然後讓你的主要打印任何值你可以做如下的事情:

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

using namespace std; 

void start(string& text); 

int main() { 

    // Create an empty 'string' object', invoking the default constructor; 
    // This gives us a valid empty string object. 
    string text; 

    ... 

    while(true) { 
     ... 
     // The `text` variable is passed by reference. 
     start(text); 

     textSurface = TTF_RenderText_Solid(font, text.c_str(), color); 
     ... 
    } 
} 

// Takes a string object by reference, and modifies it to fill it 
// with our desired text. 
void start(string& text) { 
    text += "Hello"; 
    text += " "; 
    text += "World"; 
}