How to read keyboard input in C

We can use the scanf() function to get user input in C. Here’s a quick implementation of scanf():

#include <stdio.h>

char input[100];
char *output = "Thank you for your message!";

int main(int argc, const char * argv[]) {
    
    // ask user for some input
    puts("Tell me something nice:");
    
    // grab input from keyboard via scanf()
    // don't use gets() for this, apparently it's totally evil
    scanf("%s", input);
    
    // say goodbye
    printf("%s\n\n", output);
    
    return 0;
}

scanf() will wait for the user to press Enter before giving its returned value back to our app. We must define a variable to hold its output. We can even define multiple variables, each of which will be populated with whatever is being typed in until Enter is pressed. Consider this:

 char input1[100], input2[100], input3[100];
 scanf("%s, %s, %s", input1, input2, input3);

Here we wait for three string items to be added (numbers entered will be interpreted as strings). To grab a numeric value from the keyboard, we cam use %d like so (d as in decimal, variable defined as int):

 int number;
 scanf("%d", &number);

Note the ampersand in front of our variable, without which scanf would populate a pointer. We can also mix and match keyboard input like this:

 char string[100];
 int number;
 scanf("%s, %d", string, &number);

Demo Project

You’ll find a quick demo project on GitHub, which also serves as a template on how to setup Xcode to open Terminal and allow for keyboard input when the project is run.





How to define a struct in C

Structures (or structs) in C are something like “mini-objects”: they are wrappers around multiple variables, much like the properties of an object. Since plan C doesn’t have objects, these are as close as it gets to them, and they can be quite helpful. Apple uses them extensively (think of a CGRect for example), and it’s easy to build our own.

Here’s how we can do that.

Creating a struct

We can define a struct like this:

    // define a struct
    struct cube {
        int length;
        int width;
        int height;
    };

Here we create a struct with the name of cube and define three variables inside it. They don’t have to be of the same type, you can mix and match int, float, char and all the rest of the merry gang. The variables of a struct are called members.

When defined, a struct can be seen as a template. To use it, we need to initialise a new instance of the struct and populate the member variables, like so:

    // initialilze our struct
    struct cube massiveCube;

    // and populate it with values
    massiveCube.length = 5;
    massiveCube.width = 5;
    massiveCube.height = 7;

Our instance of the struct is called massiveCube, and we can refer to its member variables by dot notation.

The whole setup can be done in one step too, like this:

    // or define and init
    struct oval {
        int width;
        int height;
    } bigOval;
    
    bigOval.height = 5;
    bigOval.width = 7;

Note here that we still need to populate the variables. Further structs from the same template can be created as shown above.

Typedef-ing a struct

If we don’t want to create new struct instances with “struct cube myCube”, we can write a type definition for a struct.

typedef struct cube MegaCube;

I’ve typedef’d previous cube structure as MegaCube. Of course we can choose any name we like here, something descriptive is always a good idea. Again, our friends at Apple to this quite frequently. Now we can create new instances simply by referring to them without the struct word and only use our own definition:

MegaCube rubiksCube;
rubiksCube.length = rubiksCube.height = rubiksCube.width = 3;

This makes our code more readable and is a way of making C code “our own”.





How to submit your apps to the App Store with Xcode 8

In case it’s been a while that you had to deal with App Store submissions, here’s a quick refresher. This assumes that iTunes Connect is ready to receive a new app or update.

Make sure that the version number and build values have both been increased if your submission is an update. In Xcode, do the following:

  • verify that the Archive Scheme is set to Release (under Product – Scheme – Edit Scheme)
  • make sure that you’ve selected “Generic iOS Device” as the active scheme
  • head over to Product – Archive to create an archive of your current version
  • the Organizer window opens, showing previously archived versions of your app (don’t delete those)
  • now hit Validate to see if there are any issues with your app
  • if all is well, hit the big blue Upload to App Store button
  • now pray that your app is approved





How to fix http load errors in Xcode

In 2016, Apple have implemented a new rule that won’t let us load data from unsecured websites anymore. That’s those beginning with http:// instead of https:// (the latter ones are secured with an SSL certificate, and hence traffic is encrypted).

When you load an unsecured source, you’ll get an error message like this:

App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file.

If a secured source of the data is available, it’s probably the easiest method to change the feed. However, if that’s not an option, we can convince Xcode to let our apps download what’s known as data from “arbitrary” sources. Here’s how to do it.

First, in Xcode, navigate to your project’s target and find the Info tab. The target is the one that has your app icon showing, NOT the blue Xcode icon (top left, in the Project Navigator).

Now right-click on any of the many lines and select “Add Row”. This adds a value to your Info.plist file. Notice a list that comes up. Either select “App Transport Security” (if you can find it), or type NSAppTransportSecurity (it usually auto-completes). The entry will change into App Transport Security.

Let’s add the appropriate values to this new entry now. Hover over your new row now and select the little plus icon that comes up, then choose “Allow Arbitrary Loads” from the list. Alternatively, type in NSALlowsArbitraryLoads. Again this value will change to Allow Arbitrary Loads. Notice that this entry is a BOOL, and it needs to be set to YES on the right hand side. Go ahead and do that.

This will be enough to allow HTTP loads inside your app from any URL. You can restrict this to only certain URLs or hosts by adding another entry to the App Transport Security line, namely “Exception Domains”. Add each domain to its own line, and only data from those will be allowed to load via HTTP. If you want to use restricted domains, make sure to set the Allow Arbitrary Loads value to NO.





How to break a for loop in C and Objective-C

Did you know that we can break out of a for loop before it finishes? It’s true – and it works with both regular for loops, as well as fast enumeration (for…in loops). And we can do it in either of two ways.

Let’s imagine we have an array with one thousand words. We’re only interested in finding a single one, and at that point we want to stop the loop.

Breaking with the break statement

The break statement will get us out of a for loop and continue programme execution after the finishing bracket of the loop. Here’s an example with a regular for loop:

    for (int i=0; i&lt;1000; i++) {

        NSString *word = [array objectAtIndex:i];
        if ([word isEqualToString:@"one"]) {

            // break the loop
            break;
        }
    }
    // execution continues here
    NSLog(@"We've broken from the loop.");

The break statement also works with fast enumeration:

    for (NSString *word in array) {

        if ([word isEqualToString:@"up"] || [word isEqualToString:@"the"]) {

            // break the loop
            break;
        }
    }

    // execution continues here
    NSLog(@"We've broken from the loop.");

Breaking with “goto label”

Goto sounds like an old BASIC command – and we can still use it in Objective C. It doesn’t work on its own though and needs an arbitrary label to which we can direct the loop after we’ve broken from it.

Here’s how we might do this with a regular for loop:

    for (int i=0; i&lt;1000; i++) {

        NSString *word = [array objectAtIndex:i];

        if ([word isEqualToString:@"the"]) {

            // break the loop with a label
            goto myLabel;
        }
    }

    myLabel:;
    NSLog(@"We've broken from the loop.");

Notice that when we declare the label where we’d like the programme to continue, we must do so with a colon (and a semi colon to finish the line).

The same principle also works with fast enumeration:

    for (NSString *word in array) {

        if ([word isEqualToString:@"up"] || [word isEqualToString:@"the"]) {

            // break the loop
            goto outer;
        } 
    }

    myLabel:;
    NSLog(@"We've broken the loop.");




How to read Command Line Input on macOS

I was building a simple Command Line Tool app for macOS. One thing the app needed was user input, i.e. it should wait for the user to type something that I’d like to make use of in the app.

Turns out it’s a rather complicated affair, and I haven’t found a comprehensive starter guide on how to actually accomplish this.

I wanted to create a Command Line Tool app that was capable of accepting text input from the Terminal window, use it, and then write output back for the user to read.

But that wasn’t enough: I also had to tell Xcode to setup the app appropriately, otherwise the Terminal window wasn’t launched – which is of course necessary for a Common Line Tool.

In this article we’ll do just that: prepare Xcode to launch Terminal, wait for input, and print it out again. Here we go.

Continue reading