An easy way to work with Standard input and Output with Objective-C

If you tried to solve online coding problems on coding websites using Objective-C, you might have realized that it is tricky to even get the website to compile your code. Its complaints will start with the libraries you are missing and they will go on with you not reading from STDIO (standard input) or not sending to the STDOUT (standard output). The code example that would make things work for one of these challenges (we will use HackerRank’s 30 day challenge Day 1 as an example) is at the bottom of the post, so you can right jump to that and copy/paste. I am fine with it as I also did some online searching to get this together. However, if you are curious about what this code is all about, then I suggest that you read on! (Please note, though, the coding website that you are using should support Objective-C. In this case, HackerRank does.)

The task! (taken from HackerRank’s website; 30 day coding challenge Day 1)

To complete this challenge, you must save a line of input from STDIN to a variable, print “Hello, World”. on a single line, and finally print the value of your variable on a second line.

First Step: Import the Objective-C foundation library:

#import <Foundation/Foundation.h>

Most of the time you will not need to import any other library because the foundation will have all the needed basic objects (including some C functions that will be needed for this task). This is important to note as we are not importing or #include’ing anything else. “#include” is the C version of “#import”. It can be seen as the primitive version of #import because #include adds the library to the code everywhere it is written. #import adds the library in the code only once.

Second Step: Create a main function.

int main()

{

//…

return 0; //return zero

}

Main function is where the Objective-C (or C, since Objective-C is based on C) code starts. When your program runs, even if you click/tap on it or call it on your terminal, it is actually the OS (Operating System of your computer –phone/tablet/watch etc.-) who is asking the program to run. That is why themain function has a return value. Because the OS expects the program to return a value to it, to confirm whether everything went OK or if there was an error. Returning 0(Zero) would mean everything went well, no issues! Any non-zero value would be an error code and every OS would use error codes to identify what went wrong when something went wrong with the program. If you are wondering whether your Objective-C project actually has a main function, yes it does! It is in the “main.m” file in every project that we create (look under Supporting Files if you cannot see it anywhere else. :-))

You will see that the main function in your main.m file has some arguments in its parenthesis (int argc, char * argv[])! These are function arguments that the main function would get as opposed to getting inputs directly through the standard input, (similar to adding an -l option to your ls command on your terminal). We do not need these for our task here as we are working with reading from the standard input and writing to the standard output only.

Now, lets fill in the empty space in our main function, shall we?

Third Step: Get the user input from the console (will be entered by the web system here, automatically) and put it into a string so it can be printed out.

char *word;

scanf(“%[^\n]s”,word);

NSString* word2 = [NSString stringWithFormat:@”Hello, World.\n%@”,[NSString stringWithCString:word encoding:NSUTF8StringEncoding]];

So, what is that char *word in there? It is a char type pointer that points a location in the memory, and that location is the beginning point of a chain of characters that will constitute a string. Remember, a string is a chain of characters in the memory. This is how a string would be represented in C. We are using the C version string instead of the NSString Class because we will need to use a C function to get the input from the standard input.

The function to get the user input (in this case it is the website’s IDE/code) from the standard input is the scanf() function. We would pass our “char *” string (variable word in this code) to it and use the formatting that we are very familiar with from NSString’s “stringWithFormat:” method. The [^/n] is just telling scanf() to exclude the return/enter character in the end. Once scanf() function gets executed we have our string “word” !.

Since it is a plain old C string, we will need to convert it to an NSString object. We are using NSString’s very useful “stringWithCstring:” method. Since the task is asking us to create a string by appending the input string to “Hello, World!”, we are using NSString’s “stringWithFormat:” method to add them together. At the end of all this, we have a beautiful NSString object ready. At this point, if we wanted to do anything else using Objecive-C, we would be able to do it!

Last Step: Printing it out to the standard output.

printf(“%s”, [word2 cStringUsingEncoding:NSUTF8StringEncoding]);

In the documentation of NSlog, Apple explains to us why we cannot use NSLog to print out on the standard output (console/terminal screen). We cannot, because NSLog prints to the Standard Error stream! In order to print to the standard output (STDOUT), we will need to ask for help from our old friend, the C function printf().

Printf()’s syntax is also similar to that of NSLog’s. We use formatting the way that we would with NSLog. The only point to notice here is that we actually convert the NSString back to a C string via “cStringUsingEncoding:” method. This might look weird as we just converted a C string to an NSString object and now we are going back to a C string! Yes we are doing that and we have reasons to do so :-)

Once we have the NSString object created, we are free to do whatever we want to do with our NSString object using Objective-C until we need to print out a string to the standard output again, which is exactly what we are doing now so all your bases are covered! Plus, if we did not do that, the string would still be a C string and the code would be 100% C. We want to be able to use Objective-C, hence the conversions!

You can read about standard input and output here and here. You can see NSLog’s brief documentation here. For a more detailed NSLog documentation, I believe you will need to do a search in your XCode documentation (or on Apple’s developers website after logging in with your Apple ID). Below is the entire code:

#import <Foundation/Foundation.h>

int main()

{

char *word;

scanf(“%[^\n]s”,word);

NSString* word2 = [NSString stringWithFormat:@”Hello, World.\n%@”,[NSString stringWithCString:word encoding:NSUTF8StringEncoding]];

printf(“%s”, [word2 cStringUsingEncoding:NSUTF8StringEncoding]);

return 0;

}

I hope this helps someone!