Reading input from file for bridge simulation program I am simulating a bridge where only one car can cross at a time. The bridge runs north south. The car arrival times and times taken to cross the bridge are given in an input file. The format is direction|arrival time,time taken to cross. The possible directions are north and south, represented by N/n and S/s respectively. An upper case letter means high priority and a lower case letter means low priority. The arrival times and time to cross are can have a value after the decimal e.g. 10.5
Examples:

N|6.0,10.0
n|4.5,5.5

Here is my function, which is pretty ugly but works:
void getInput(char * inFile)
{
    enum direction_t {NORTH, SOUTH};
    direction_t direction;
    enum priority_t {HIGH, LOW};
    priority_t priority;
    string line;
    ifstream inFile(inFile);
    if(!inFile.good())
    {
        cerr &lt;&lt; &quot;can't open input file&quot;;
        exit(1);
    }
    while(getline(inFile, line))
    {
        char first = line.at(0);//first letter signifies direction and priority
        if(first == 'n')
        {
            direction = NORTH;
            priority = LOW;
        }
        else if(first == 'N')
        {
            direction = NORTH;
            priority = HIGH;
        }
        else if(first == 's')
        {
            direction = SOUTH;
            priority = LOW;
        }
        else if(first == 'S')
        {
            direction = SOUTH;
            priority = HIGH;
        }
        else
        {
            cerr &lt;&lt; &quot;invalid direction given: &quot; &lt;&lt; first &lt;&lt; endl;
            //exit(1);
        }
        size_t commaIndex = line.find(&quot;,&quot;, 2);//know first character is letter, second is |
        string firstNumber = line.substr(2, commaIndex-2);
        string secondNumber = line.substr(commaIndex+1, line.length());
        cout &lt;&lt; &quot;firstNumber: &quot; &lt;&lt; firstNumber &lt;&lt; &quot; secondNumber &quot; &lt;&lt; secondNumber &lt;&lt; endl;   
    }

I was wondering if the way I use enum is good. Any tips for making code more readable and more compact are appriaciated.
Parameter shadowing a local variable:

The first issue with your code that prevented in from compiling with Clang is the
inFile parameter of getInput() that shadows the ifstream instance of the same name.

Your compiler seems to be more forgiving with that problem. If you are using GCC, I recommend using the -Wshadow warning flag to enable warnings of this kind of variable name shadowing/redeclaration. This category of bugs can be particularly hard to track in a scenario where both variables are of the same type.

Reserved suffix:

The _t suffix is reserved by the POSIX standard (read this), so it is best if avoided.
Consider renaming direction_t and priority_t to Direction and Priority.

Const correctness:

The filename parameter of the function is a read-only string, so it should at least
be a const char *. But since this is C++ code, prefer a standard string and pass it by const reference:

void getInput(const std::string &amp; filename)


Error handling:

You did right by using std::cerr to report errors, however, exit()ing after the error is logged
seems like a very crude way of handling it. Consider throwing an exception or even
making the function return a boolean false.

Using namespace:

You are probably using namespace std somewhere, judging by the lack of the std:: prefix in the library calls. This is best if avoided as it defeats the purpose of a namespace, which is allowing equal names to coexist without clashes. Read this thread for a more in-depth discussion.

Data driven solution:

There is a more data driven and flexible way of handling the conversion between the chars
read from file to the Direction/Priority enums than an if chain or a switch statement.

You could instead use a map keyed by a char. This way, expanding and adding more chars
is simpler and involves less code change. You could even externalize the map to a file
and load it dynamically at runtime if you wanted.

Following is the refactored code with the changes above mentioned applied to it plus
the use of a std::map as a lookup table. The map associates a char (the key)
with a pair of [Direction, Priority]. Making the conversion form the file data a lot more concise.

#include &lt;iostream&gt;
#include &lt;fstream&gt;
#include &lt;string&gt;
#include &lt;map&gt;

bool getInput(const std::string &amp; filename)
{
    enum Direction { NORTH, SOUTH };
    enum Priority  { HIGH,  LOW   };

    const std::map&lt;char, std::pair&lt;Direction, Priority&gt;&gt; lookupTable = {
        { 'n', { NORTH, LOW  } },
        { 'N', { NORTH, HIGH } },
        { 's', { SOUTH, LOW  } },
        { 'S', { SOUTH, HIGH } }
    };

    Priority    priority;
    Direction   direction;
    std::string line;

    std::ifstream inFile(filename);
    if (!inFile.good())
    {
        std::cerr &lt;&lt; "can't open input file";
        return false;
    }

    while (getline(inFile, line))
    {
        const char key = line.at(0); // first letter signifies direction and priority

        const auto entry = lookupTable.find(key);
        if (entry != lookupTable.end())
        {
            direction = entry-&gt;second.first;
            priority  = entry-&gt;second.second;
        }
        else
        {
            std::cerr &lt;&lt; "invalid direction given: " &lt;&lt; key &lt;&lt; std::endl;
        }

        size_t commaIndex = line.find(",", 2); // know first character is letter, second is |
        std::string firstNumber  = line.substr(2, commaIndex - 2);
        std::string secondNumber = line.substr(commaIndex + 1, line.length());
        std::cout &lt;&lt; "firstNumber: " &lt;&lt; firstNumber &lt;&lt; " secondNumber " &lt;&lt; secondNumber &lt;&lt; std::endl;
    }

    return true;
}




So it turn out that the OP's compiler is missing a few C++11 features that prevent the code provided above from compiling. It can be fairly easily adapted to support older compilers though, if we are willing to add a few not so elegant workarounds. Here is one way to adapt it using an aux function that keeps a static std::map:

enum Direction { NORTH, SOUTH, DIR_INVALID };
enum Priority  { HIGH,  LOW,   PRI_INVALID };

std::pair&lt;Direction, Priority&gt; lookup(char key)
{
    typedef std::map&lt; char, std::pair&lt;Direction, Priority&gt; &gt; TableType;

    static bool isTableInitialized = false;
    static TableType lookupTable;

    // One time initialization
    if (!isTableInitialized)
    {
        lookupTable.insert(std::make_pair( 'n', std::make_pair(NORTH, LOW)  ));
        lookupTable.insert(std::make_pair( 'N', std::make_pair(NORTH, HIGH) ));
        lookupTable.insert(std::make_pair( 's', std::make_pair(SOUTH, LOW)  ));
        lookupTable.insert(std::make_pair( 'S', std::make_pair(SOUTH, HIGH) ));
        isTableInitialized = true;
    }

    TableType::const_iterator entry = lookupTable.find(key);
    if (entry != lookupTable.end())
    {
        return (*entry).second;
    }

    // Not found / invalid key
    return std::make_pair(DIR_INVALID, PRI_INVALID);
}

bool getInput(const std::string &amp; filename)
{
    Priority    priority;
    Direction   direction;
    std::string line;

    std::ifstream inFile(filename.c_str());
    if (!inFile.good())
    {
        std::cerr &lt;&lt; "can't open input file";
        return false;
    }

    while (getline(inFile, line))
    {
        // first letter signifies direction and priority
        const char key = line.at(0);

        // Lookup the conversion table:
        const std::pair&lt;Direction, Priority&gt; entry = lookup(key);

        if ((entry.first != DIR_INVALID) &amp;&amp; (entry.second != PRI_INVALID))
        {
            direction = entry.first;
            priority  = entry.second;
        }
        else
        {
            std::cerr &lt;&lt; "invalid direction given: " &lt;&lt; key &lt;&lt; std::endl;
        }

        size_t commaIndex = line.find(",", 2); // know first character is letter, second is |
        std::string firstNumber  = line.substr(2, commaIndex - 2);
        std::string secondNumber = line.substr(commaIndex + 1, line.length());
        std::cout &lt;&lt; "firstNumber: " &lt;&lt; firstNumber &lt;&lt; " secondNumber " &lt;&lt; secondNumber &lt;&lt; std::endl;
    }

    return true;
}


It has its drawback, but should work just the same. It is also quite a bit more code to get it done. One important thing to keep in mind is that initialization order of the lookup table is not thread safe, so don't try to use this in a concurrent program.