The biggest problem with using C is going to be that it does not have the any sort of mapping function in the standard library. You will need this to implement the Symbol Table for your assembler.
In Python, for instance, one can simply write
symbol_table[label] = current_addr
where label is a string and current_addr is an integer, and later
addr = symbol_table[label]
to get the address out of the symbol table. In C this requires a lot of code; you will want to search the net for "hash table" to find appropriate code.
As to how to know the address for labels, this is why you need to read the assembly source file twice. Pass 1 figures out the addresses for all symbols and stores them in the Symbol Table; it does not generate any output. Pass 2 generates the output using the symbol values saved during Pass 1.
--Mark