Trying To Get SDL2 Text Input Working

Hi,

Trying to get SDL2 Text Input working with no success.
Here is the code:

#ifndef INPUT
#define INPUT

class Input
{
public:

	Input(void);
	virtual ~Input(void);

    bool DEBUG;

    bool EXIT_Game;

    SDL_Event Event;

    SDL_Keycode KeyOnKeyboardPressedByUser;

    char *text;

    int DelayAllUserInput;

&

while ( SDL_PollEvent(&Event) )
{
    switch (Event.type)
    {
        case SDL_QUIT:
            EXIT_Game = true;
            return;
            break;

        case SDL_WINDOWEVENT:
            if (Event.window.event == SDL_WINDOWEVENT_RESIZED || Event.window.event == SDL_WINDOWEVENT_SHOWN)
            {
                screens->ScreenIsDirty = true;
                logic->GameDisplayChanged = true;
            }
            break;

        case SDL_KEYDOWN:
            KeyOnKeyboardPressedByUser = SDL_GetKeyFromScancode(Event.key.keysym.scancode);

            if (KeyOnKeyboardPressedByUser == SDLK_LSHIFT || KeyOnKeyboardPressedByUser == SDLK_RSHIFT)
                KeyOnKeyboardPressedByUser = -1;
            break;

        case SDL_TEXTINPUT:
            strcat(text, Event.text.text);
            break;

        default:
            break;
    }
}

Pressing on a letter key now crashes my SDL2 game?
What am I doing wrong?

I don’t call:
"SDL_StartTextInput();"
until I need to use it in the new high score name input with keyboard screen function.

Any help would be appreciated, thanks!

JeZxLee

Did you allocate space for the text?

Thanks for the reply…

How can I fix my code above to fix the crash?
(I am new to SDL2 Text Input)

Thanks!

JeZxLee

Sorry, but I tried to follow the following tutorial:
https://wiki.libsdl.org/Tutorials/TextInput

Little confused now on how to make this work…
People in the IRC room got mad and told me to use this SDL Text Input…

JeZxLee

That code example is somehow missing the actual memory allocation for text.

Hey, if you’re already using C++, why not go with std::string?

Here’s a working example:

textinput.cpp
#include <clocale>
#include <string>
#include <iostream>

#include <SDL.h>

static void Printw(std::string & txt, bool cr = false, bool flush = false) {
#if _WIN32
	const char * dstformat = "UTF-16LE";
#else
	const char * dstformat = "UTF-32";
#endif

	if (cr)
		std::wcout << L"\r";

	wchar_t * wchr = (wchar_t*)SDL_iconv_string(dstformat, "UTF-8", txt.c_str(), txt.size() + 1);
	if (wchr) {
		std::wcout << wchr;
		SDL_free(wchr);
	} else {
		std::wcout << L"\rError! Could not convert string." << std::endl;
	}

	if (flush)
		std::wcout << std::flush;
}

int main(int argc, char *argv[])
{
	int run = 1;
	std::string text;
	SDL_Window * window;

	std::setlocale(LC_ALL, "");

	if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) < 0 ) {
		return 1;
	}

	window = SDL_CreateWindow("TextInput", 50, 50, 50, 50, SDL_WINDOW_SHOWN);
	if (!window) {
		SDL_Quit();
		return 2;
	}

	while (run) {
		SDL_Event e;
		while (SDL_PollEvent(&e)) {
			if (e.type == SDL_QUIT) {
				run = 0;
			} else if (e.type == SDL_TEXTINPUT) {
				text.append(e.text.text);
				Printw(text, true, true);
			} else if (e.type == SDL_KEYDOWN) {
				if (e.key.keysym.sym == SDLK_ESCAPE) {
					run = 0;
				} else if (e.key.keysym.sym == SDLK_BACKSPACE) {
					if (text.size() > 0) {
						std::string clearstr(text.size(), ' ');
						Printw(clearstr, true);
						// Removing multi-byte characters from the UTF-8 string.
						while (text[text.size() - 1] < -64) {
							text.erase(text.size() - 1);
						}
						text.erase(text.size() - 1);
						Printw(text, true, true);
					}
				}
			} else if (e.type == SDL_KEYUP) {
				if (e.key.keysym.sym == SDLK_RETURN) {
					text.append(1, '\n');
					Printw(text, true);
					text.clear();
				}
			}
		}

		SDL_Delay(1);
	}

	SDL_DestroyWindow(window);
	SDL_Quit();

	return 0;
}