Elliot Smith
Elliot Smith

Reputation: 307

Reading from a file and check for file endings

I am trying to do the following tasks in Go;

  1. Read from a file
  2. Backup the file
  3. Overwrite and perform actions based on the files output on a character by character basis (which may include newLine characters or "b" for example)

Unfortunately, I am stuck on step 3 and would like some assistance with "new line" characters (i.e. "/n"). I have tried using filesText, err := ioutil.ReadFile(fileNameAndDirectory) but unfortunately if I try and check for file endings after converting filesText to a string I am unable to detect new line characters (i.e. If files text is "/nhello/n" then the following code snippet will not print the string "match"

filesText, err := ioutil.ReadFile(fileNameAndDirectory) 
if (string(filesText)[:2]) == "/n") {
    fmt.Println("match")
}

).

Is there something that I can do to detect new lines without reading the file line by line manually?

Example: If the file contents is "r/n3$/n;" then I should able to perform 6 predefined actions (one for for each character) as I move from left to right over the files contents.

Upvotes: 2

Views: 1169

Answers (1)

peterSO
peterSO

Reputation: 166744

We can only guess. You haven't defined your problem clearly. Please clarify your specific problem or add additional details to highlight exactly what you need. Provide sample input and output.


The Go Programming Language Specification

After a backslash, certain single-character escapes represent special values:

\n   U+000A line feed or newline

Here's a guess:

lines.go:

package main

import (
    "fmt"
    "io/ioutil"
    "os"
    "strings"
)

func lines(data []byte) {
    text := string(data)
    for i, j := 0, 0; j >= 0; i += j + 1 {
        var line string
        j = strings.IndexByte(text[i:], '\n')
        if j < 0 {
            line = text[i:]
            if len(line) == 0 {
                continue
            }
        } else {
            line = text[i : i+j+1]
        }
        // process line
        fmt.Printf("%d %q\n", len(line), line)
    }
}

func main() {
    filename := `test.file`
    data, err := ioutil.ReadFile(filename)
    if err != nil {
        fmt.Fprintln(os.Stderr, err)
        return
    }
    fmt.Printf("%d %q\n", len(data), data)
    lines(data)
}

Output:

$ cat test.file
line1
line2
line3
$ go run lines.go
18 "line1\nline2\nline3\n"
6 "line1\n"
6 "line2\n"
6 "line3\n"

Comment:

I'll try and clarify it through an example. Let say that I have a file with contents "ara/n;>$g9s", my application will perform an action defined by that input character as it moves through the contents of the file. I.e. If "a" does action 1, "r" does action 2, "/n" does action 3 and so on then the input above will perform the following actions 1,2,1,3... in that order. However, if you turn the byte array to a string then I'm unable to identify "/n" characters since they appear to be removed despite the string having the same formatting as before if you print it out or concat it into a file. – Elliot Smith

Why do you write /n for a newline character! The newline character U+000A, as I've already pointed out, is written as \n.

For example,

package main

import "fmt"

func es(s string) {
    for _, r := range s {
        switch r {
        case 'a':
            fmt.Printf("action 1 for %q\n", r)
        case 'r':
            fmt.Printf("action 2 for %q\n", r)
        case '\n':
            fmt.Printf("action 3 for %q\n", r)
        default:
            fmt.Printf("action ? for %q\n", r)
        }
    }
}

func main() {
    b := []byte("ara\n;>$g9s")
    s := string(b)
    es(s)
}

Playground: https://play.golang.org/p/3J0pxXh3Wkc

Output:

action 1 for 'a'
action 2 for 'r'
action 1 for 'a'
action 3 for '\n'
action ? for ';'
action ? for '>'
action ? for '$'
action ? for 'g'
action ? for '9'
action ? for 's'

Revised Question:

Example: If the file contents is "r/n3$/n;" then I should able to perform 6 predefined actions (one for for each character) as I move from left to right over the files contents. Elliot Smith


Why do you write /n for a newline character! The newline character U+000A, as I've already pointed out, is written as \n.

For example,

package main

import "fmt"

func es(s string) {
    for _, r := range s {
        switch r {
        case 'a':
            fmt.Printf("action for %q\n", r)
        case 'r':
            fmt.Printf("action for %q\n", r)
        case '\n':
            fmt.Printf("action for %q\n", r)
        default:
            fmt.Printf("action for %q\n", r)
        }
    }
}

func main() {
    file := []byte("r\n3$\n;")
    s := string(file)
    es(s)
}

Playground: https://play.golang.org/p/X1gtrPRmlqq

Output:

action for 'r'
action for '\n'
action for '3'
action for '$'
action for '\n'
action for ';'

Upvotes: 2

Related Questions