C++ 界面上的奇怪文本打印
我不知道这里发生了什么,尽管这很酷而且奇怪的令人毛骨悚然,但这并不是我真正想要的 基本上;我正在尝试实现一个程序,在黑色界面上缓慢地键入文本。我正在使用SDL2和SDL2_TTF来实现这一点,到目前为止一切都进展顺利 目前,我让它在黑屏上键入“嘿;)”,但下面是发生的情况: 忽略FPS计数器,这只是Nvidia 我真的不知道发生了什么,我使用的字体是“Hack Regular.ttf” 关于代码:C++ 界面上的奇怪文本打印,c++,sdl,truetype,C++,Sdl,Truetype,我不知道这里发生了什么,尽管这很酷而且奇怪的令人毛骨悚然,但这并不是我真正想要的 基本上;我正在尝试实现一个程序,在黑色界面上缓慢地键入文本。我正在使用SDL2和SDL2_TTF来实现这一点,到目前为止一切都进展顺利 目前,我让它在黑屏上键入“嘿;)”,但下面是发生的情况: 忽略FPS计数器,这只是Nvidia 我真的不知道发生了什么,我使用的字体是“Hack Regular.ttf” 关于代码: #include<iostream> #include<SDL.h> #
#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;
}
#包括
#包括
#包括
#包括
无效句柄事件(SDL_事件e,bool*quit){
而(SDL_事件(&e)>0){
如果(e.type==SDL\u退出){
*退出=真;
}
}
}
无效渲染(SDL_渲染器*渲染器,SDL_纹理*文本渲染器,SDL_Rect srcret,SDL_Rect dstrect){
SDL_渲染器(渲染器);
SDL_RenderCopy(渲染器、textToRender、srcrect和dstrect);
SDL_渲染器呈现(渲染器);
}
void printToConsole(标准::字符串消息,字符*文本){
对于(int i=0;i
如果很难阅读,我很抱歉,我觉得没有必要使用多个类
需要注意的是,“f”是“asdf”的最后一个字母。我最初将文本定义为,不知道它为什么从这里开始。在下面的语句中,您定义了一个占用1字节内存的变量,并将整数值102(也称为“f”)存储在ascii中:
char text = 'asdf'; //This is the text that has been rendered.
上述说法存在几个问题:
- 单个
变量只能存储一个字符、一个字节的内存。您正在尝试分配4。只有最后一个值保持不变char
- 您试图使用单个字符,而您想使用
- 您正在对c字符串使用单引号语法
- 由于变量只存储一个字节,因此该单个值之后的下一个内存字节是未定义的—它来自程序中其他地方的任意内存,可能是堆栈上下一个分配的任何值
- 如果您正确地声明了该变量,那么稍后您将尝试写入只读内存,因为c字符串文本通常加载到只读内存中
char*
类型传递,将该值传递给呈现例程:
textSurface = TTF_RenderText_Solid(font, &text, color);
然而,在C/C++中,char*
习惯性地用于存储指向a的指针,即带有最终空终止符的字符序列。在接受char*
参数作为c字符串的API中,您需要传递一个指向末尾带有空终止符的字符序列的指针
因为它希望传递的值是c字符串,所以它将从内存中盲读,直到看到一个值为0的字节。由于它读取的内容超过了为该变量(只有一个字节)预留的内存的末尾,因此它将读取任意内存,直到它幸运地在某处找到一个零为止——这就是它显示垃圾的原因
你怎么解决这个问题?好吧,这取决于你将如何得到你的字符串
使用您提供的代码,没有真正的理由分配您自己的c字符串。如果您有string
对象,可以使用c\u str()
方法访问char*
c-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);
}
如果您希望具有引用语义,即在main中声明一个text
变量,传递给程序的其他部分对其进行修改,然后让main打印设置的任何值,您可以执行以下操作:
#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";
}
#包括
#包括
#包括
使用名称空间std;
无效开始(字符串和文本);
int main(){
//创建一个空的“字符串”对象,调用默认构造函数;
//这为我们提供了一个有效的空字符串对象。
字符串文本;
...
while(true){
...
//通过引用传递'text'变量。
开始(文本);
textSurface=TTF_RenderText_Solid(字体,text.c_str(),颜色);
...
}
}
//通过引用获取字符串对象,并对其进行修改以填充它
//我们想要的文本。
无效开始(字符串和文本){
text+=“你好”;
文本+=”;
文本+=“世界”;
}
为什么start()
使用char
参数而不是char*
?无论哪种方式,都可以使用<