www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Noob questions

reply 0x10001 <changdoelee gmail.com> writes:
Hello, i've hit some roadblocks while trying to learn D, i'll try 
to explain each of them below :

1: Why does using readf in a function causes readln in following 
functions to "skip"(or do as if i had pressed enter?)
Here's an example code(excuse me if it doesn't appear formatted) :

import std.stdio;
import std.string;

void main() {
	ubyte menuint;
	writeln("test");
	readf(" %s", &menuint);
	if (menuint == 1) {
		foo();
	} else {
		bar();
	}
}

void foo() {
	string a = strip(readln());
	writeln(a);
}

void bar() {
	string b = strip(readln());
	writeln(b);
}
The code after the readf function just prints two newlines 
without even asking for input.


2: Why can i do whatever to strings that represents filenames but 
using stdin for filenames with (strip(readln()) always causes a 
"No such file or directory" error?

I've tried the same with chop(readln()), the test file is named 
"TEST.TXT" and while using ''' File file = File("TEST.TXT", "r") 
''' works, but doing the same with a variable that contains the 
same exact filename obtained with <<std.string.strip(readln())>> 
or <<std.string.chop(readln())>> always causes a "No such file or 
directory" error. I've tried to make it print the read filename 
before and it visually appears to be the exact same.
I'm on Windows in case this is a compatibility problem and it 
works as expected on everything else.

3: How can files be accessed once opened with read access?(as 
described in Ali Çehreli's Programming in D, chapter 19) Am i 
right when assuming they are just void[] arrays that can be 
"casted" to another array type(if appropriate within current 
context) resulting in what's called a buffer? I'm asking because 
i've been trying to make a simple program with std.zlib that 
uncompresses/compresses all zlib files that follow a certain name 
pattern, only problem is that apparently the std.file.write 
function doesn't pass compilation because it can't use anything 
that has "File" in its type, what am i supposed to do then?(the 
exact error is "template std.file.write cannot deduce function 
from argument types !()(File, void[])", i got the same error with 
the std.stdio.write function)

Here's the code in question that i have trouble with :
		if (exists(filename)) {
			writeln("file found!");
			File efile = File(filename, "r");
			File rawfile = File(filename ~ ".out", "w");
			void[] efile_buf1 = lire(filename); // alias for std.file.read
			ubyte[] efile_buf2 = cast(ubyte[]) efile_buf1;
			rawfile.écrire(uncompress(efile_buf2)); // alias for 
std.file.write
			succ(namecounter);


Thanks to everyone in advance.
Apr 24 2019
next sibling parent Andre Pany <andre s-e-a-p.de> writes:
On Wednesday, 24 April 2019 at 22:44:17 UTC, 0x10001 wrote:
 Hello, i've hit some roadblocks while trying to learn D, i'll 
 try to explain each of them below :

 [...]
Regarding question 1, I had the same question some days ago https://forum.dlang.org/thread/akootxwiopsltifwdwxh forum.dlang.org For question 2, can you show your complete coding? It should work, I assume there might be a subtitle issue in your logic. Kind regards Andre
Apr 24 2019
prev sibling parent reply Erinaceus <ErinaceusEuropaeus users.noreply.github.com> writes:
In case you have not solved the 3rd problem yet (your code is 
almost there),
it can be fixed by replacing this line:
	rawfile.écrire(uncompress(efile_buf2)); // alias for 
std.file.write
with this one:
	(filename ~ ".out").écrire(uncompress(efile_buf2));

The lines that open files using std.stdio.File are not needed and 
can be removed:
	File efile = File(filename, "r");
	File rawfile = File(filename ~ ".out", "w");

std.file.write works pretty much like this:
	void write(string filename, void[] writeThis) {
		import std.stdio;
		File f = File(filename, "w");
		f.rawWrite(writeThis);
		f.close();
	}

It expects a filename as an argument (not a std.stdio.File 
structure representing an open file). std.file.read also expects 
a filename, your code is calling that one correctly.
Using std.stdio.File is not necessary here because 
std.file.read/write open and close the files on their own.


About your 2nd problem: its hard to tell whats going on without 
more complete code. You may want to inspect the problematic 
string using something like this:
	string correct = "test.txt";
	string tricky = std.string.strip(readln());
	writeln("c: ", cast(ubyte[]) correct);
	writeln("t: ", cast(ubyte[]) tricky);

This is going to print numeric codes of all bytes in the string 
and reveal any potentially invisible characters (like spaces, 
line-ending markers, tabs etc.), like this:
	c: [116, 101, 115, 116, 46, 116, 120, 116]
	t: [116, 101, 115, 116, 46, 116, 120, 116, 13]
Apr 26 2019
parent 0x10001 <changdoelee gmail.com> writes:
On Thursday, 25 April 2019 at 02:39:22 UTC, Andre Pany wrote:
 On Wednesday, 24 April 2019 at 22:44:17 UTC, 0x10001 wrote:
 Hello, i've hit some roadblocks while trying to learn D, i'll 
 try to explain each of them below :

 [...]
Regarding question 1, I had the same question some days ago https://forum.dlang.org/thread/akootxwiopsltifwdwxh forum.dlang.org For question 2, can you show your complete coding? It should work, I assume there might be a subtitle issue in your logic. Kind regards Andre
Your workaround with " %s\n" worked perfectly, thank you! i wasn't able to reproduce the second issue however despite the source file not having changed since, if i encounter it again i'll try to do what Erinaceus said.(Well i already did but since i wasn't able to re-reproduce the problem it prints the same two ubyte arrays.) On Friday, 26 April 2019 at 09:04:26 UTC, Erinaceus wrote:
 In case you have not solved the 3rd problem yet (your code is 
 almost there),
 it can be fixed by replacing this line:
 	rawfile.écrire(uncompress(efile_buf2)); // alias for 
 std.file.write
 with this one:
 	(filename ~ ".out").écrire(uncompress(efile_buf2));

 The lines that open files using std.stdio.File are not needed 
 and can be removed:
 	File efile = File(filename, "r");
 	File rawfile = File(filename ~ ".out", "w");

 std.file.write works pretty much like this:
 	void write(string filename, void[] writeThis) {
 		import std.stdio;
 		File f = File(filename, "w");
 		f.rawWrite(writeThis);
 		f.close();
 	}

 It expects a filename as an argument (not a std.stdio.File 
 structure representing an open file). std.file.read also 
 expects a filename, your code is calling that one correctly.
 Using std.stdio.File is not necessary here because 
 std.file.read/write open and close the files on their own.


 About your 2nd problem: its hard to tell whats going on without 
 more complete code. You may want to inspect the problematic 
 string using something like this:
 	string correct = "test.txt";
 	string tricky = std.string.strip(readln());
 	writeln("c: ", cast(ubyte[]) correct);
 	writeln("t: ", cast(ubyte[]) tricky);

 This is going to print numeric codes of all bytes in the string 
 and reveal any potentially invisible characters (like spaces, 
 line-ending markers, tabs etc.), like this:
 	c: [116, 101, 115, 116, 46, 116, 120, 116]
 	t: [116, 101, 115, 116, 46, 116, 120, 116, 13]
The changes you proposed worked, and thank you for your explanation, i can't reproduce my second problem anymore but here is the original code anyway :
import std.stdio;
import std.file;
void main() {
	writeln();
	string filename = strip(readln());
	File file = File(filename, "r");
	File ofile = File((filename ~ ".out"), "w");
	if (exists(filename)) {
		writeln("success : ","'", filename, "'");
	} else writeln("bad");
}
May 01 2019