This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
SquidDev's profile picture

[1.74][SMP/SSP] Error on printing unprintable characters

Started by SquidDev, 11 August 2015 - 06:01 AM
SquidDev #1
Posted 11 August 2015 - 08:01 AM
Version:
Tested in 1.74

Description
When printing characters with a code of 192 or above, the Window API will explode with the message "window:94: Arguments must be the same length". This appears to be the call to term.blit.

This is a variation of 'the string bug', as you can see here - 0xC0 is hex for 192 and so the string length is being changed. A simple fix would be for the window API to only print characters between 32 and 127.

Expected Result
I'd expect ? to be printed in place of unprintable characters.

Reproduction Steps:

-- Run Lua:
print(string.char(191)) -- Prints ?
print(string.char(192)) -- window:94: Arguments must be the same length
CraftedCart #2
Posted 15 August 2015 - 03:09 PM
Well, I seem to be getting that error trying to print unprintable characters. I can't easily remove them from my code though, I'm trying to create a Github client, and whenever a search has an unprintable character, it crashes the program. Anyone know of any workarounds?
Bomb Bloke #3
Posted 16 August 2015 - 01:07 AM
I deal with it in Note by way of this function:

	local function safeString(text)
		local newText = {}
		for i = 1, #text do
			local val = text:byte(i)
			newText[i] = (val > 31 and val < 127) and val or 63
		end
		return string.char(unpack(newText))
	end

You could, if you wanted, perform some function overrides to make implementing it easier:

local oldPrint, oldBlit, etc = print, term.blit, etc

function print(text)
	return oldPrint(safeString(text))
end

function term.blit(text, fg, bg)
	return oldBlit(safeString(text), fg, bg)
end

etc

But the less times you run the conversion, the faster your code'll run.
Edited on 15 August 2015 - 11:11 PM
CraftedCart #4
Posted 16 August 2015 - 11:56 AM
I deal with it in Note by way of this function:

	local function safeString(text)
		local newText = {}
		for i = 1, #text do
			local val = text:byte(i)
			newText[i] = (val > 31 and val < 127) and val or 63
		end
		return string.char(unpack(newText))
	end

You could, if you wanted, perform some function overrides to make implementing it easier:

local oldPrint, oldBlit, etc = print, term.blit, etc

function print(text)
	return oldPrint(safeString(text))
end

function term.blit(text, fg, bg)
	return oldBlit(safeString(text), fg, bg)
end

etc

But the less times you run the conversion, the faster your code'll run.

Oh… I can do

:byte()
to get the id of a letter…
Thanks for that, it solved the issue :)/>