Left part of a string plus spaces

Dear all,

I would like to print the player’s input into a (simulated) “window” which is 20 chars wide. So if the player’s input is 5 letters I would like to add 15 spaces, and if the player’s input is 24 letters I’d cut the last 4 letters off. In a ficticious BASIC dialect that would look like

str=left(input+"(20 spaces)",20)

How can I do this in Inform 6? I got the input, but the rest is a mystery to me.

Thanks and kind regards,
Grues

If you’re using StdLib 6.12, try routine PrintToBuffer() as defined in Parser.h.

The return value will tell you how many characters were “printed” to the buffer array, and you can fill in the rest with spaces as necessary.

You can output the contents of the buffer at any point via a loop with print (char)...

1 Like

Okay but what if the input is longer than the max width I allow for output? If I define an array for PrintToBuffer() I need to define its length, right? Let’s say 20. What if NextWord() is longer than 20 chars?

Oh – sorry, I misread your question. I thought that you wanted to transfer a string to an array, not player input! Can you provide a little more detail of what you’re trying to accomplish – maybe a transcript sample?

NextWord() may not be the best tool here – it will return either a dictionary word (bounded to the maximum character length) or zero for something unrecognized.

1 Like

Is this after getting the player’s input and parsing it with the normal routines? Or is getting the input from the keyboard part of the process here?

1 Like

Well, the plan is to print the player input into a box with fixed length. Like,

+--------+
| test   |
+--------+

I thought I’d determine the player input through

wn = consult_from;
wd = NextWord();

and then add some 20 spaces to it and then cut that string at length X and just print it. And now it looks to me like Inform 6 is so un-C++ that that’s actually not such an easy task. :expressionless:

OK, easy enough.

You are correct that I6 is fundamentally unlike C when it comes to text. (The reasons have to do with the Z-machine architecture.)

There is a global array called buffer (the name of the array, not the type in this case). That directly stores the characters captured from the player’s command.

The return value of WordAddress(1) would be the start of the portion of the array containing the first typed word, and that address can itself be treated as an array. The return value of WordLength(1) gives the number of characters detected.

You should be able to just loop through those addresses to print out the characters up to the max of 20 or what came back from WordLength(). You can use spaces for any balance left over.

Note that to actually store the information for later use you’ll want a separate array (using the buffer type of array), so it’s probably best to copy from the command buffer to that first, then print it out from your storage space.

If that’s not clear, I can work out a functional example.

EDIT: I should add that I think someone worked out an I6 library extension that does the best that it can to emulate C’s string functions, which may be of interest to you. You can find it on IF Archive.

2 Likes

Almost got it, I think.

j=WordLength(1);
for(k=0 : k<20 : k++){
	if(k<j){
		print (char)WordAddress(1)-->k;}
	else{
		print " ";}
	}

compiles, but produces a RTE:

Programming error: tried to print (char) 26479, which is not a valid ZSCII character code for output

Any ideas?

That’s close! You’re accessing the address as a word array, but characters are bytes.

Change

print (char)WordAddress(1)-->k;

to

print (char)WordAddress(1)->k;
2 Likes

It works! Thaaaanks!!!1 :slight_smile: