2015-11-03 116 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"; 
}