Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

If you are designing a function which should conver a string to an integer, how would you convert an empty string? The question is only about this one particular input value (empty string).

Between throwing an ExcStringIsEmpty exception and converting to 0 options I prefer the first. It seems more logical to me. Because when you perform an opposite conversion from integer 0 you will hardly convert it to an empty sting but to a string 0 instead.

share|improve this question

closed as not a real question by jk., Joris Timmermans, gnat, MichaelT, GlenH7 May 23 '13 at 0:00

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.If this question can be reworded to fit the rules in the help center, please edit the question.

6  
"How would you convert an empty string?" - however the requirements told me to. If the requirements didn't tell me, I'd ask the client (after berating the analyst, which might be me of course). –  AakashM May 22 '13 at 13:22
    
@AakashM I'm asking about what is more correct/logical. –  Kolyunya May 22 '13 at 13:25
3  
@kolyunya - more logical would be a string class that doesn't have a toInt method, because in general strings can't logically be converted to ints. –  Joris Timmermans May 22 '13 at 13:31
    
@MadKeithV it seems perfectly logical to me to convert a 555 string to 555 number. No? Strings with characters distinct from numerals should cause exception. –  Kolyunya May 22 '13 at 13:34
    
@MadKeithV the question is not about classes. Let's say you are designing a function, converting a string to a number. –  Kolyunya May 22 '13 at 13:36

6 Answers 6

An empty string doesn't represent any integer, so at face value your question has a trivial answer - do not convert an empty string to a valid integer.

The question behind the question seems to be "how to design a robust non-surprising string-to-int conversion utility". This is tricky - consider the following additional cases:

  • What string number representations will you accept? There is more than decimal - the following strings are also integer number representations in common use: 0x0A, 2x10^2, 10E5, 08,...
  • Will you consider converting strings representing floating point numbers to integer numbers?
  • If you answer yes to the previous question, what rounding or truncation will you use?
  • What about rational numbers?
  • You can probably come up with a few more if you tried.

So all in all the actual answer to your question should be to use the string-to-number conversion library functions supplied with your current language and framework, if they have any. If there are no implementations for your situation, then look at other languages or libraries for inspiration of how to handle those cases in your own implementation. If you document what your conversion function does, then it will not (or at least should not) surprise the clients of your function.

share|improve this answer
1  
Consider the following cases I asked only about one particular case - you mentioned 5 others... –  Kolyunya May 22 '13 at 13:49
    
The problem is atoi returns 0 in that case, which I think is incorrect. –  Kolyunya May 22 '13 at 13:57
3  
@Kolyunya: atoi comes from C. And atoi("") results in undefined behaviour, because there is no value to represent the string with (atoi does not provide for any error handling). –  Bart van Ingen Schenau May 22 '13 at 14:33
1  
+1 - if the requirements only say "convert string to integer" and there is no further specification available, the logical thing to do would be going into some error state - in Java I'd throw an IllegalArgumentException –  ftr May 22 '13 at 15:06
1  
@Kolyunya: Your case does not exist in isolation. An answer that only satisfies that one (edge) case would be misinformed, and disingenuous as a solution. –  Steve Evers May 22 '13 at 17:16

If you're converting string to int similar to JavaScript's parseInt function, then you would probably want to have '' return NaN or throw an exception, as you said.

JavaScript returns NaN, but if your language doesn't have that convention or feature you should throw an exception or return a null value.

share|improve this answer
    
JavaScript doesn't have an int type. NaN is a floating-point value. –  kevin cline May 22 '13 at 18:00

Considering that 0 has been invented to fill a void in positional representation of numbers,

Considering that most spreadsheet applications interpret an empty cell as a 0 value and that this behaviour is expected by users,

It is not far fetched to convert an empty string to an integer of value 0.

The reverse conversion doesn't need to be symetrical (unless otherwise specified on your project).

share|improve this answer

Why do you only need one string-to-int method? Why not three:

/** Throws exception if string is unparsable */
int strToInt(String s) throws NumberFormatException

/** Returns null if string is unparsable */
Integer strToIntOrNull(String s)

/** zero if string is unparsable */
int strToIntOrZero(String s)

Now the client of your code can choose and know what to expect if a corner-case is hit.

share|improve this answer

There's another potential answer here, and I think akalenuk hinted at it. Use a maybe monad or some other similar, option type.

For example C#/.NET has Nullable<T>, which isn't the same but is pretty close, but restricted to Nullable<int> it should be enough.

public static Nullable<int> toInt(string s)
{
    int i = 0;
    if (int.TryParse(s, out I))
        return new Nullable<int>(i);

    return new Nullable<int>();
}

Also remember, that the transformation toInt is not 1 to 1 and invertible. You are transforming from a large set, the set of all possible strings, to the set of all possible integers (bounded by your types... which is relevant, but not that much). So it's not necessary, or even sensible to assume that toString is the inverse of toInt. The case where toInt(s).HasValue == false covers the case (set of all strings) - (set of all number strings)

However, we're not done.

Is this actually the general case? If so then what about number strings for which the value is too large to fit into an integer? Clearly, it's still a number. If it's not the general case then does your use case bound the set of output values within the range of an integer? If so, then you're done.

... if not, then we have to consider whether we need another type (Double? BigInteger?) BigInteger seems like it might fit the general case, still yet bounded by memory (OutOfMemoryException is possible).

In the end, if we're trying to shoot for something as general as possible, I'd go with:

public static Nullable<BigInteger> toInt(string s)
{
    BigInteger bi = new BigInteger();
    if (BigInteger.TryParse(s, out bi))
        return new Nullable<BigInteger>(bi);

    return new Nullable<BigInteger>();
}

Now, for the big sex... let's do it functionally (F# + options):

let toInt s = 
    match BigInteger.TryParse s with
    | (true, parsed) -> Some parsed
    | (false, _) -> None
share|improve this answer

Of course it depends on how the function is meant to be used.

These are really two separate (though not independent) design decisions:

  1. What counts as invalid input?
  2. What to do about invalid input?

About that first decision, any of "+3", "03", "0x3", "3.0", "3.", "3e0", "3 ", " 3" could in some domain reasonably be declared a valid or invalid int representation. Likewise, though we don't customarily represent the zero-value with an empty string, it can be a perfectly reasonable choice to declare that this function considers "" a representation of zero.

The second decision is more substantial. A well-written function might promise to handle invalid input with:

  • a standard way of signaling an error (exception, separate status return)
  • a standard way of marking the absence of a value (null return, "optional"/"maybe" return type, separate return-presence indicator)
  • a special "error" int return that is known to be invalid or highly unlikely in the domain the function is dealing with (e.g. -1 or maxint)
  • a default int return (0)
  • a well defined best-effort result (converting "123abc" to 123)
  • an undefined return value (but at least a return value)
  • completely undefined behaviour (no promises - might corrupt memory or crash)

Throwing an exception is obviously a common choice in the modern world, but depending on how the function will be used, any of those could make sense. If it will be called a jillion times in a super-tight loop across 10k cores (think Google scale), sometimes the right decision is to write other code so it never passes in invalid inputs.

And two or three of those choices make f("") return 0, assuming "" is invalid input in the first place.

I don't think a more concrete answer would truly be more useful here, but just in case that's all you're after: If we know we're designing a function for general use (e.g. in a new language's stdlib), a good rule of thumb is to treat invalid inputs in the highest-level way available, typically exception. But that should be abandoned if it's clearly overkill: e.g. if the rest of the lib only uses exceptions for catastrophic failures, or if catching them is too verbose or slow compared to how often the function will be used. (Think for a moment why Java of all languages avoids throwing exceptions on arithmetic ops.)

share|improve this answer

Not the answer you're looking for? Browse other questions tagged or ask your own question.