Thread overview |
---|
September 03, 2020 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? |
September 03, 2020 Re: Unable to open filename passed as command line argument | ||||
---|---|---|---|---|
| ||||
Posted in reply to Curious | 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 Re: Unable to open filename passed as command line argument | ||||
---|---|---|---|---|
| ||||
Posted in reply to Curious | 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 Re: Unable to open filename passed as command line argument | ||||
---|---|---|---|---|
| ||||
Posted in reply to user1234 | 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
|
Copyright © 1999-2021 by the D Language Foundation