digitalmars.D.learn - Unable to open filename passed as command line argument
Given the following: =====a====== void main(string[] args) { FILE* fp = fopen(args[1].ptr, "r"); if (!fp) throw new Exception("fopen"); } =====b====== void main(string[] args) { FILE* fp = fopen(args[1].dup.ptr, "r"); if (!fp) throw new Exception("fopen"); } Why does a fail but b succeed?
Sep 03 2020
On 9/3/20 1:47 PM, Curious wrote:Given the following: =====a====== void main(string[] args) { FILE* fp = fopen(args[1].ptr, "r"); if (!fp) throw new Exception("fopen"); } =====b====== void main(string[] args) { FILE* fp = fopen(args[1].dup.ptr, "r"); if (!fp) throw new Exception("fopen"); } Why does a fail but b succeed?try `toStringz`: ```D import std.string : toStringz; void main(string[] args) { FILE* fp = fopen(args[1].toStringz, "r"); if (!fp) throw new Exception("fopen"); } ``` The reason is that args are D strings (that contains no terminating 0) but `fopen` gets C string (null terminated) so your `a` variant fails because the filename becomes wrong as there is no terminating 0. Your `b` variant works in fact accidentally because after duplication in new memory after filename 0 appears due to random reason (for example all that memory area zeroed by allocator).
Sep 03 2020
On Thursday, 3 September 2020 at 10:47:04 UTC, Curious wrote:Given the following: =====a====== void main(string[] args) { FILE* fp = fopen(args[1].ptr, "r"); if (!fp) throw new Exception("fopen"); } =====b====== void main(string[] args) { FILE* fp = fopen(args[1].dup.ptr, "r"); if (!fp) throw new Exception("fopen"); } Why does a fail but b succeed?version b works by accident/UB. You need to null terminate your filename if you use the C library functions: --- void main(string[] args) { FILE* fp = fopen((args[1] ~ '\0').ptr, "r"); if (!fp) throw new Exception("fopen"); } --- otherwise what you get as args are D dynamic arrays (a payload made of .ptr and .length) so you can use std.file or std.stdio to open a file using the "D main" arguments (it's not the like "C main"). --- void main(string[] args) { import std.stdio; File f = File(args[1], "r"); } ---
Sep 03 2020
On Thursday, 3 September 2020 at 11:12:49 UTC, user1234 wrote:On Thursday, 3 September 2020 at 10:47:04 UTC, Curious wrote: otherwise what you get as args are D dynamic arrays (a payload made of .ptr and .length) so you can use std.file or std.stdio to open a file using the "D main" arguments (it's not the like "C main"). --- void main(string[] args) { import std.stdio; File f = File(args[1], "r"); } ---Okay. Got it! Thanks
Sep 03 2020