简体   繁体   中英

Swift's readLine() is nil when I enter a long string in STDIN

I am trying to solve this HackerRank's problem about dynamic programming. I think I have come with a solution, probably not very efficient but still, I am trying.

I submitted my code and it failed to pass a large test case, so I am trying to test it myself using that test case. The problem is when I enter the input data Xcode doesn't respond, it doesn't crash, but it doesn't continue the execution of the code.

First I had this code to read a single line that contains n space-separated integers, which in this case is 68,738.

let arr = readLine()!.characters.split(" ").map({ Int(String($0))! })

After a few time (several seconds, maybe even minutes) the code crashed saying that it found nil while unwrapping an optional value.

So I tried and split that instruction as follow:

let input = readLine()!
let arr = input.characters.split(" ").map({ Int(String($0))! })

Here I would expect the code to crash in the second line, trying to map the input string to an array of integers. But the code crashed while trying to readLine(). The input string was 370,112 long.

I also tried to use this code in order to at least get the string input:

let input = readLine()
let arr = input!.characters.split(" ").map({ Int(String($0))! })

But input is nil. I assume here that the input string was too long, but shouldn't be 2,147,483,648 on a 32-bytes CPU? I guess that's enough space, right?

I googled to find if there'd be any limit in readLine() but found nothing. I would try to solve this problem in another language but I'd really like to make it in Swift. Is there something I am not seeing?

readLine() is a wrapper around the stdio getline function, and that function requires only that a newline character occurs within the first SSIZE_MAX characters of the input. On the 64-bit OS X platform, SSIZE_MAX is 2^63 - 1 which means that this is only a theoretical limitation.

So readLine() is not the problem, it can read arbitrarily long lines as long as they fit into your computers memory.

But it seems that you can not paste more than 1023 characters into the Xcode debugger console. ( Edit: This was also observed at Read a very long console input in C++ ).

Running the program in a Terminal with input redirection from a file is one option to solve the problem:

$ ./myProgram < /path/to/inputData.txt

Another option is to add

freopen("/path/to/your/inputData.txt", "r", stdin)

at the beginning of the Swift program. This redirects the standard input to read from the given file. The advantage of this method is that you can still debug your program in Xcode.

As mentioned by @MartinR, the problem was I was trying to test this with Xcode, which seems to have some limits for input strings. I tried from the terminal and it worked just the way it should.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM