Fortran77: Checking if character array index is empty - if-statement

I have a character array names(10)*6. I'm looping through I = 1:10 and writing the values of names(I).
The problem is that names periodically is missing values, and if thats the case for a particular names(I), I want to skip it.
I was trying to do something like this.
IF(names(I) .NE. 0) THEN
WRITE(4,202) names(I)
ENDIF
I got an error telling me I'm dumb for comparing characters to 0. That makes sense.
What should I compare it to? Empty spaces like this? How do I check if its not defined or empty after I declared space for it?
IF(mychar(I) .NE. ' ') THEN
WRITE(4,202) names(I)
ENDIF
The goal is to only issue the write command if there is actually something there. :-)
Edit Note: I may not initialize this array. I am wondering what the default value for an undefined declared index is, or if there is a function to check if a character array index is empty.

You might be interested in the intrinsic len_trim function. As always Read The Fortran Manual.

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),' ');

Rocket Universe string delete a character question

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.

String array unusable after setting it to 0 using memset

I have a class property which is an array of strings (std::string command[10]). When I assign some string value to it, it stop the program execution. As you can see below I've a string variable tempCommandStr which I assign to my property. I don't know what the error could be, but I've the print statement after assignment which is never executed, while the one preceding it is.
//Declared in class header
std::string command[10];
// Part of function which is causing problem.
string tempCommandStr(commandCharArray);
printf("%s\n", tempCommandStr.c_str()); // Prints fine.
this->command[i] = tempCommandStr; // Something goes wrong here. i is set to some correct value, i.e. not out of range.
printf("%s\n", this->command[i].c_str()); // Never prints. Also program stops responding.
// I noticed that getting any value from the array also stops the execution.
// Just the following statement would stop the program too.
printf("%s\n", this->command[i].c_str());
It's not just this property, I also have another array which has the same problem. What could be causing this? What's actually going wrong (look at edit)? Is there another better way to do this?
I'm running the program on an MBED so I've limited debugging options.
EDIT:
I found the problem, I was cleaning the array before using to remove any previous values by memset(command, 0, sizeof(command));. This is was causing the problem. Now I use the clear function on each item in array as following. This fixed the execution problem.
for (int i = 0; i < sizeof(command)/sizeof(*command); i++){
command[i].clear();
}
Question: Why does setting the string array to 0 using memset makes it unusable?
Why does setting the string array to 0 using memset makes it unusable?
Because you're obliterating the values held in the string class, overwriting them all with 0s. A std::string has pointers to the memory where it's storing the string, character count information, etc. If you memset() all that to 0, it's not going to work.
You're coming from the wrong default position. Types where 'zeroing out' the memory is a meaningful (or even useful) operation are special; you should not expect any good to come from doing such a thing unless the type was specifically designed to work with that.

What does `.Z` mean in SAS?

Apologies for such an entirely uninformed question, but I don't know any SAS and just need to know what one line of code does, so I hope someone can help.
I have a loop over an array of variables, and an if clause that is based on a comparison to .Z, but this variable is defined nowhere, so I'm guessing this is some sort of SAS syntax trick. Here's the loop:
ARRAY PTYPE{*} X4216 X4316 X4416 X4816 X4916 X5016;
DO I=1 TO DIM(PTYPE);
IF (PTYPE{I}<=.Z) THEN PUT &ID= PTYPE{I}=;
END;
So on the first iteration, the loop would check whether the value in X4216 is smaller than .Z, and then...? ID is another varuable in the dataset, but I have no idea what's happening on the right hand side of that if clause. I've briefly consulted the SAS documentation to figure out that ampersands refer to macros, but my knowledge of SAS is to limited to understand what's happening.
Can anyone enlighten me?
.Z is a special missing value. In SAS a missing value (what you might call a NULL value) is indicated by a period. There are also 27 other special missing values that are indicated by a period followed by a letter or an underscore. The missing values are distinct and are all considered smaller than any actual number. .Z is the "largest". So PTYPE{I}<=.Z is basically testing if the value is missing. You could instead use MISSING(PTYPE{I}) to make the same test. The right hand side is writing out the name and the value of the variable in the array with a missing value and also the name and value of the variable named in the macro variable ID.

Translating C++ to Pep/8 Assembly Language-- Char Array

As the title states, I am currently having issues translating a C++ program to PEP/8.
The first part of the program deals with input and output of a char array. The strInput function simply reads in character values into an array until the user hits enter or the size of the array reaches 63. When the user hits enter, a '0' is stored instead of '\n'. If the array reaches [63], a '0' is stored in [64]. The strOut function prints the contents of the array until a '0' is found or the length of the array is reached.
I have been playing around the current assembly code, however I am continuously prompted for input. I think the problem might be with the X register and/or the offset from the stack. Any insight would be appreciated.
C++ code: https://gist.github.com/anonymous/b690427aaf465dd7326a
Pep/8: https://gist.github.com/anonymous/37a51a34f7eecb15f4ee
I believe you need to 'SUBSP' at the beginning of your functions, to make room for the variables, versus 'ADDSP'.
EDIT: I made that change, amongst other things, and I cannot figure it out either. Let everyone know if you find the solution.