Thread overview
Unable to open filename passed as command line argument
Sep 03, 2020
Curious
Sep 03, 2020
drug
Sep 03, 2020
user1234
Sep 03, 2020
Curious
September 03, 2020
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?
September 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).
September 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");
}
---
September 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