Unable to use backslash `\` in Golang os.Arg variable - go

I have made a program in Golang and I am trying to use a file as the first argument when launching my program.
For example: ./goprogram.exe C:\Acidic\image.png
When my program tries to use the os.Arg[1] variable which should be the link to the image.png file, it returns the string without any of the backslashes (C:Acidicimage.png).
How can I use the whole string of an argument without characters being escaped?
I have made a little example:
package main
import (
"fmt"
"os"
)
func main() {
if len(os.Args) >= 2 {
fmt.Println(os.Args[1])
}
}
I run go run args.go C:\Users\image.png and it outputs C:Usersimage.png

Put any argument between quotes:
./goprogram.exe "C:\Acidic\image.png"

The issue appears to be your shell. Try quoting the file path:
./goprogram.exe 'C:\Acidic\image.png' # prevents escape sequence execution
A string fo type C:\Acidic\image.png (with single \'s) is not a valid string in Go (invalid escape sequence \A, etc) and would not even compile.

Related

Why _(underscore) ignored in output?

I would like to know the reason behind the output of this program.
package main
Program
import (
"fmt"
)
func main() {
a := 1_00_000
fmt.Println(a)
}
Output
100000
How come the underscore is ignored in the output. What is the use of this new feature in Go?
It's not ignored in the output; it's ignored in the source code. The underscores are a convenience to make large number literals in code easier to read; the literal is still an integer, and integers don't contain underscores. You could always use a string of course:
a := "1_00_000"
fmt.Println(a)
Underscores as separators were added as a new feature in Go 1.13: https://golang.org/doc/go1.13#language
Underscores are just digit separators.This new feature is introduced in Go 1.13 to improve readability.It is not printed along with the number.
The digits of any number literal can be separated (grouped) using underscores, such as in 1_000_000, 0b_1010_011 to make it more readable.
d := 9795696874578
d := 9_795_696_874_578 // thousand separators
Here underscored literals are much easier to read.

Don't understand func strings.TrimLeft in Go

I'm trying to test code that uses func strings.TrimLeft. I needed to see an MVCE of it in action, so I went to the API specification.
It came with an example, which I exported, with the following code:
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Print(strings.TrimLeft("¡¡¡Hello, Gophers!!!", "!¡"))
}
Upon running it, you get Hello, Gophers!!!
I decided to prepend the input string, changing the code to
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Print(strings.TrimLeft("irrelevant text¡¡¡Hello, Gophers!!!", "!¡"))
}
The result string is the whole input string: irrelevant text¡¡¡Hello, Gophers!!!
Aren't at least the cutset characters supposed to be removed?!
It is an industry standard that trim implies a proper suffix or prefix.
trimLeft will only remove matching characters from the beginning of the string and stop on the first non-match. In your example, the "i" of "irrelevant" is the first character it checks. It fails the check, so it stops trimming (i.e. it does nothing).
trimRight, by comparison, removes matches starting from the end of the string in descending index order.
Aren't at least the cutset characters supposed to be removed?!
All of the ones at the beginning of the string. There are zero of those, so zero characters are removed.

cmd line parameter string.Contains behaving differently from hardcoded parameter

I'm looking to get some clarification on why these two strings.Contains() calls behave differently.
package main
import (
"strings"
"os"
"errors"
"fmt"
)
func main() {
hardcoded := "col1,col2,col3\nval1,val2,val3"
if strings.Contains(hardcoded, "\n") == false {
panic(errors.New("The hardcoded string should contain a new line"))
}
fmt.Println("New line found in hardcoded string")
if len(os.Args) == 2 {
fmt.Println("parameter:", os.Args[1])
if strings.Contains(os.Args[1], "\n") == false {
panic(errors.New("The parameter string should contain a new line."))
}
fmt.Println("New line found in parameter string")
}
}
If I run this with
go run input-tester.go col1,col2,col3\\nval1,val2,val3
I get the following
New line found in hardcoded string
parameter: col1,col2,col3\nval1,val2,val3
panic: The parameter string should contain a new line.
goroutine 1 [running]:
panic(0x497100, 0xc42000e310)
/usr/local/go/src/runtime/panic.go:500 +0x1a1
main.main()
/home/user/Desktop/input-tester.go:21 +0x343
exit status 2
I can see that the string printed out is the same format as the string that is hardcoded yet the string.Contains() doesn't find the "\n".
I'm guessing this is an oversight on my part. Can anyone explain what I'm missing or misunderstanding?
It behaves differently because in hardcoded \n is considered as new line parameter.
And in command line arguments , argument type is string, where given condition is for "\n" which is considered as new line parameter.
Simply ` \n compaires with two consecutive characters "\" and "n" not with "\n" a new line character.
So for command line arguments use,
if strings.Contains(os.Args[1], `\n`) == false {
panic(errors.New("The parameter string should contain a new line."))
}
Reference : https://golang.org/ref/spec#String_literals
Raw string literals are character sequences between back quotes, as in foo. Within the quotes, any character may appear except back quote. The value of a raw string literal is the string composed of the uninterpreted (implicitly UTF-8-encoded) characters between the quotes; in particular, backslashes have no special meaning and the string may contain newlines.

Why does go fmt allow empty brackets?

I was just wondering why these brackets haven't been removed after running go fmt, does their use have a function?
package main
import "fmt"
func main() {
fmt.Println("Hello, 世界")
{
{
{
}
}
}
}
Example here, thanks.
They basically function like an internal namespace, so any definition(s) you put in between an encapsulating brace will not be visible outside of it.
// ... other code above ...
{
a := 5 // declare a
}
a = 5 // compiler error, a is undeclared
And plus formatting tools such as gofmt or autopep8 (for python) do not modify a given file beyond adding/removing whitespace or newline characters to already existing code.
Brackets on their own denote code Blocks. From the spec:
A block is a possibly empty sequence of declarations and statements within matching brace brackets.
These are part of the Go syntax, and go fmt formats them according the its formatting rules.

how to put a backquote in a backquoted string?

is it possible to print back quotes in Go using back quotes : something like this:
package main
import "fmt"
func main() {
fmt.Println(```) // for example I can do it with double quotes "\""
}
package main
import "fmt"
func main() {
// back ` quote
fmt.Println((`back ` + "`" + ` quote`))
}
Raw string literals are character
sequences between back quotes ``.
Within the quotes, any character is
legal except back quote. The value of
a raw string literal is the string
composed of the uninterpreted
characters between the quotes; in
particular, backslashes have no
special meaning and the string may
span multiple lines. String
literals
You can also do it with single quotes:
package main
import "fmt"
func main() {
fmt.Printf("%c\n", '`')
}
https://golang.org/pkg/fmt#Printf
TLDR
fmt.Println("\x60")
\x: Hex see fmt
6016
9610
1408 matches the character ` grave accent

Resources