Rocket Universe string delete a character question - universe

This one has me wondering if I may be missing a function or something.
Have a string, example TZ118-AH01
I simply want to remove the second character and was wondering if there was a simple way of doing this, cannot use CONVERT as the second character may be repeated in the string.
Currently figuring I have to something like
VALUE = STRING[1,1]:STRING[3,LEN(STRING)-2]
Which seems a bit cumbersome.
Anyone have a nifty work around?

VALUE = STRING[1,1]:STRING[LEN(STRING)-2]
Would be syntactically the same if you are sure that the length won't ever be less that 2, and if for some reason it does you don't mind stopping the entire call stack.
If the first and second characters are known commodities, you could use field and fudge up the field count in the forth variable to something high like 1000, but that is kludgy and relies on the first and second character not being the same.
The best was would be a function or subroutine to concatenate a new new string iterating through the character array and skipping the second iteration.
SUBROUTINE Remove2ndChar(StringOut,StringIn)
StringOut=""
CC=LEN(StringIn)
FOR C=1 TO CC
If C NE 2 THEN
StringOut:=StringIn[C,1]
END
NEXT C
RETURN
This is not necessarily what you are looking for, but it is probably going to be more execution safe.
Good Luck.

Related

SAS function findc with null character argument

Very incidentally, I wrote a findc() function and I submitted the program.
data test;
x=findc(,'abcde');
run;
I looked at the result and nothing is unnormal. As I glanced over the code, I noticed the findc() function missed the first character argument. I was immediately amazed that such code would work.
I checked the help documentation:
The FINDC function allows character arguments to be null. Null arguments are treated as character strings that have a length of zero. Numeric arguments cannot be null.
What is this feature designed for? Fault tolerance or something more? Thanks for any hint.
PS: I find findw() has the same behavior but find() not.
I suspect that allowing the argument to be not present at all is just an artifact of allowing the strings passed to it to be of zero length.
Normally in SAS strings are fixed length. So there was no such thing as an empty string, just one that was filled with spaces. If you use the TRIM() function on a string that only has spaces the result is a string with one space.
But when they introduced the TRIMN() and other functions like FINDC() and FINDW() they started allowing arguments to functions to be empty strings (if you want to store the result into a variable it will still be fixed length). But they did not modify the behavior of the existing functions like INDEX() or FIND().
For the FINDC() function you might want this functionality when using the TRIMN() function or the strip modifier.
Example use case might be to locate the first space in a string while ignoring the spaces used to pad the fixed length variable.
space = findc(trimn(string),' ');

Is it possible to initialize characters to a number, n, based on how many characters the user inputs?

I had a homework question where I had to ask the user for a character and use that character to create the image of the letter C. It sparked an interest and I wanted to try and make a program that asks the user for a letter, word, or sentence of their choice and have it create the letter, word, or sentence out of a character they choose. For exmaple if the user inputs "Hi" with the character X, the out put would be:
X X X
X X
XXXX X
X X X
X X X
This is probably beyond my league because I'm a newbie to c++ and coding in general, however I enjoy messing around with code so its something I wanted to try.
My idea is to make a switch statement that loops through every letter and replaces each letter with the corresponding letter output. However I can't figure out how I would initialize the infinite amount of possible characters the user inputs.
Is there a way to make the input a string and then translate the string into individual char types? From then I can just loop through each character and use the switch statement to switch it out. Also is there a way to count how many characters there are so I can use that to make the loop? For example in python I could just use len("string") and it would give an integer value. Is there anything like that in C++?
I know there is probably a lot simpler and cleaner ways to go about this project, but I'm very limited to the little knowledge I know right now.
Any input would be awesome, thanks.
Is there a way to make the input a string
Yes, and it sounds like you already know how to do this part.
and then translate the string into individual char types?
Yes, if str is a variable holding the string, and i is the index of the character you want to get, then str[i] is that character. (Remember the first character is at index 0)
Also is there a way to count how many characters there are so I can use that to make the loop?
Yes, if str is a variable holding the string, then use str.length() (assuming it's a string rather than a C-style array of characters).
For example in python I could just use len("string") and it would give an integer value. Is there anything like that in C++?
See above.

C++ if/else grid system

I am trying to create a C++ program that will move an X on a 4x4 grid and display each move. We are not allowed to use arrays because we haven't learned how yet. I know that I am supposed to use 16 if/else statements, but I am not sure what to do from there. I know there is an easier way than mapping out each possible option because that would take forever!!! What do I do???
EDIT: It is only allowed to move up/down/left/right. And what I mean by display each move it is first supposed to display the user's starting point (which I've already set up) and then it is supposed to print grids with successive moves on them including all of the previous moves until it reaches the end point.
Note: I originally wrote this answer based on assumptions about the task that turned out to be wrong. However, I'll leave the answer up as I believe it might still contain useful information for the OP.
When you have x different possible situations, you don't always need an if/else with x branches. The trick is to find a way to use the same computation (typically one or more mathematical expressions, and possibly loops) to handle all or most of the situations.
In this case, there are indeed 16 different positions on a 4x4 grid, and one way to represent a position is to store its row and column number (each a value between 0 and 3). By using two loops, one inside the other (nested loops), you can generate all 16 combinations of row and column position. I'll assume now that you're supposed to print e.g. . on the empty cells of the grid. Inside the inner loop, you need to figure out whether you should print a . or an X. What question should you ask in order to figure that out? Simply "is the row and column number that the nested loops are currently at the same row and column number as the location of the X?"
Edit after seeing your update: Even when working with a grid, arrays are only needed when you have to store information about every cell, so one can sometimes get away without an array if you can generate the grid information from fewer pieces of information (such as the position of the X). However, if you need to keep track of the previous positions, you need an array (either one- or two-dimensional) in order to do it elegantly. I would say that the "no arrays" restriction of this task is not educational, as it forces an unnatural and very cumbersome way to solve this task. :-( (However, if your instructor subsequently gives the same task and allows you to use loops, it will be a good demonstration of why loops are useful.)
What you could do is to use 16 bool variables (all set to false initially) with names such as grid00, grid01, grid02, grid03, grid10, ..., grid33. Then make two methods, bool isOccupied(int row, int column) and void occupy(int row, int column) that use 16-way if/else statements to allow you to easily read and change the variable that corresponds to a given position.
I know that I am supposed to use 16 if/else statements, but I am not
sure what to do from there.
If this is a constraint on your solution given to your by your instructor, that means that you will need to handle each of the 16 possible grid locations in a separate {} block. You'll have to have an enum representing each of the pairs. like:
e_1_1, e_1_2, e_1_3, e_1_4,
e_2_1, e_2_2, e_2_3, e_2_4,
e_3_1, e_3_2, e_3_3, e_3_4,
e_4_1, e_4_2, e_4_3, e_4_4,
and you'll have to manually update the current position to a new one in the switch statement. Keep track of your current position in a variable called something like 'position'.
I know there is an easier way than mapping out each possible option
because that would take forever!!!
Welcome to programming. ;-)
Copy and paste is your friend and this problem of having to write a lot of similar but slightly different code is fairly common to many programming tasks. Becoming a good programmer means learning how to avoid largely duplicate code when possible. You are not there yet, or you wouldn't have to ask. So this first step will be an important lesson for you. A bit of pain will help you appreciate how much better the approach you will use the next time will be.
But this isn't that much work. An experienced C++ programmer could knock this out in less than 5 to 10 minutes. Moderately experienced, perhaps 20 to 30. It might take a learning programmer a few hours or more.
There are more concise ways to handle this problem without requiring 16 separate blocks, however, none of them are easier to understand. If this a requirement for a class learning project, then you will find it beneficial to do it first this way, then as a next step, try to do it with more complex logic.
Suggestions
An experienced programmer would define the move possibilities as an enum. Then the moves would be handled inside the {} blocks for the if statements using a switch statement that handled each of the four enums corresponding to the four moves. If you don't know the switch statement yet you can use an if ... else if ... else if ... that checks for each of the four moves.
Start with handling just the first upper left corner position moves for a smaller 2 x 2 grid. Then add each of the other three positions for the 2 x 2 grid. Once you have that working you should be able to understand easily how to extend the solution to a 4 x 4 and arbitrarily larger grid.
You'll want to have a function that prints the position array that gets called after every move. For now, you'll have to check the value of the enum and print manually. Something like:
Is position == e_1_1? print '* else print '_'
Is position == e_1_2? print '* else print '_'
Is position == e_1_3? print '* else print '_'
Is position == e_1_4? print '* else print '_'
print a newline
Is position == e_2_1? print '* else print '_'
Is position == e_2_2? print '* else print '_'
Is position == e_2_3? print '* else print '_'
Is position == e_2_4? print '* else print '_'
etc.
Some pointers for easy debugging:
Set the values for an enum for up, down, left, and right to something you can print out and follow easily, i.e. e_up = 'u' and e_down = 'd'. That will make it easier to debug if you don't have an IDE that will let you easily see the enum values, and you can print out the moves directly in the beginning.
Make your changes to the code in small increments. Run the code and once you know that the part you added works, move on. If you add too much at once it is much harder to figure out where things are broken, especially when you are new.
Future Solution with Arrays
Some hints: You'll want to use a two-dimensional array.
Try this on a 2 x 2 array first to make your life simpler. Then when the logic works, change the array size. To make this process easier use a const integer to define a value that you use to define the arrays and the printing using a for loop so that when you change the constant from:
const int array_size = 2
to
const int array_size = 4
the rest of the code will just work. For extra credit, support arrays of differing height and width by using separate constants for array_height and array_width. Learn to do it well and the way a pro would do it and you'll develop pro habits and earn pro wages much more quickly.
Remember to use a for loop for printing the rows and columns that uses the constants you defined.
You'll want to have the code running a loop looking for input, then processing the move, then printing out the new grid.

String-Conversion: MBCS <-> UNICODE with multiple \0 within

I am trying to convert a std::string Buffer - containing data from a bitmap file - to std::wstring.
I am using MultiByteToWideChar, but that does not work, because the function stops after it encounters the first '\0'-character. Seems like it interprets it as the end of the string.
When i dont pass -1 as the length-parameter, but the real length of the data in the std::string-Buffer, it messes the Unicode-String up with characters that definetly not appeared at that position in the original string...
Do I have to write my own conversion function?
Or maybe shall i keep the data as a casual char-array, because the special-symbols will be converted incorrectly?
With regards
There are many, many things that will fail with this approach. Among other things, extra bytes may be added to your data without your realizing it.
It's odd that your only option takes a std::wstring(). If this is a home-grown library, you should take the trouble to write a new function. If it's not, make sure there's nothing more suitable before writing your own.

Is this an acceptable use of "ASCII arithmetic"?

I've got a string value of the form 10123X123456 where 10 is the year, 123 is the day number within the year, and the rest is unique system-generated stuff. Under certain circumstances, I need to add 400 to the day number, so that the number above, for example, would become 10523X123456.
My first idea was to substring those three characters, convert them to an integer, add 400 to it, convert them back to a string and then call replace on the original string. That works.
But then it occurred to me that the only character I actually need to change is the third one, and that the original value would always be 0-3, so there would never be any "carrying" problems. It further occurred to me that the ASCII code points for the numbers are consecutive, so adding the number 4 to the character "0", for example, would result in "4", and so forth. So that's what I ended up doing.
My question is, is there any reason that won't always work? I generally avoid "ASCII arithmetic" on the grounds that it's not cross-platform or internationalization friendly. But it seems reasonable to assume that the code points for numbers will always be sequential, i.e., "4" will always be 1 more than "3". Anybody see any problem with this reasoning?
Here's the code.
string input = "10123X123456";
input[2] += 4;
//Output should be 10523X123456
From the C++ standard, section 2.2.3:
In both the source and execution basic character sets, the value of each character after 0 in the
above list of decimal digits shall be one greater than the value of the previous.
So yes, if you're guaranteed to never need a carry, you're good to go.
The C++ language definition requres that the code-point values of the numerals be consecutive. Therefore, ASCII Arithmetic is perfectly acceptable.
Always keep in mind that if this is generated by something that you do not entirely control (such as users and third-party system), that something can and will go wrong with it. (Check out Murphy's laws)
So I think you should at least put on some validations before doing so.
It sounds like altering the string as you describe is easier than parsing the number out in the first place. So if your algorithm works (and it certainly does what you describe), I wouldn't consider it premature optimization.
Of course, after you add 400, it's no longer a day number, so you couldn't apply this process recursively.
And, <obligatory Year 2100 warning>.
Very long time ago I saw some x86 processor instructions for ASCII and BCD.
Those are AAA (ASCII Adjust for Addition), AAS (subtraction), AAM (mult), AAD (div).
But even if you are not sure about target platform you can refer to specification of characters set you are using and I guess you'll find that first 127 characters of ASCII is always have the same meaning for all characters set (for unicode that is first characters page).