2016-06-25 1 views
0

키, 공백, 숫자 및 개행으로 구성된 줄이있는 파일을 구문 분석하려고합니다.스캐너마다 한 줄에 여러 개의 토큰을 사용하는 것이 더 좋은 방법일까요?

내 코드는 작동하지만 나에게 올바르게 냄새를 맡지 않습니다. 스캐너를 사용하는 더 좋은 방법이 있습니까? 특히, for-loop 내부에 Scan()을 사용하지 않는 것이 좋습니다.

func TestScanner(t *testing.T) { 
    const input = `key1 62128128\n 
key2 8337182720\n 
key3 7834959872\n 
key4 18001920\n 
key5 593104896\n` 
    scanner := bufio.NewScanner(strings.NewReader(input)) 
    scanner.Split(bufio.ScanWords) 
    for scanner.Scan() { 
     key := scanner.Text() 
     scanner.Scan() 
     value := scanner.Text(); 
     fmt.Printf("k: %v, v: %v\n", key, value) 
    } 
} 
+1

. 반복마다 하나의 그룹화를 보장하기 때문에 새 라인에서 분리하는 것이 더 관용적 인 것처럼 보입니다. 그런 다음 반복 내에서'strings.Split()'을 사용하십시오. 다른 사람들이 읽기 쉽고 논리가 무엇을하는지 이해하는 것처럼 관용적입니다. – eduncan911

답변

3

당신은 오류를 검사 항상 input\n를 사용하지 않아야합니다.
작업 예제 코드 :

package main 

import (
    "bufio" 
    "fmt" 
    "strings" 
) 

func main() { 
    const input = `key1 62128128 
key2 8337182720 
key3 7834959872 
key4 18001920 
key5 593104896` 
    scanner := bufio.NewScanner(strings.NewReader(input)) 
    scanner.Split(bufio.ScanWords) 
    for scanner.Scan() { 
     key := scanner.Text() 
     if !scanner.Scan() { 
      break 
     } 
     value := scanner.Text() 
     fmt.Printf("k: %v, v: %v\n", key, value) 
    } 
} 

출력 :

package main 

import "fmt" 
import "strings" 

func main() { 
    const input = `key1 62128128 
key2 8337182720 
key3 7834959872 
key4 18001920 
key5 593104896` 
    rdr := strings.NewReader(input) 
    for { 
     k, v := "", 0 
     n, _ := fmt.Fscan(rdr, &k, &v) 
     if n != 2 { 
      //fmt.Println(err) 
      break 
     } 
     fmt.Printf("%T: %[1]v, %T: %[2]v\n", k, v) 
    } 
} 

출력 :

string: key1, int: 62128128 
string: key2, int: 8337182720 
string: key3, int: 7834959872 
string: key4, int: 18001920 
string: key5, int: 593104896 

k: key1, v: 62128128 
k: key2, v: 8337182720 
k: key3, v: 7834959872 
k: key4, v: 18001920 
k: key5, v: 593104896 

은 또한이 같은 원하는 형식으로 스캔 Fscan를 사용할 수있다

+0

감사합니다. 흥미롭게도 Scanner는 내 시스템에서 Fscan보다 약 5 ~ 10 배 빠르며 반복적으로 100k 회선 파일을 처리합니다. –

+0

@ adapt-dev : 빠른 입력 검색을 원하면 다음을 참조하십시오. http://stackoverflow.com/questions/31333353/faster-input-scanning –

1

사실 Scan()이 입력을 확인하고 Err()을 사용하여 얻을 수있는 오류를 설정하므로 완벽하게 안전합니다.

그래서 Scan()이 실패했는지 확인하려면 루프의 끝에서 많은 examples으로 표시해야합니다.

코드는 일이 없을시 : 나는 ScanWords에 분할하지 않을

func TestScanner(t *testing.T) { 
    const input = `key1 62128128 
key2 8337182720 
key3 7834959872 
key4 18001920 
key5 593104896` 
    scanner := bufio.NewScanner(strings.NewReader(input)) 
    scanner.Split(bufio.ScanWords) 
    for scanner.Scan() { 
     key := scanner.Text() 
     scanner.Scan() 
     value := scanner.Text(); 
     fmt.Printf("k: %v, v: %v\n", key, value) 
    } 

    if err := scanner.Err(); err != nil { 
     fmt.Printf("Invalid input: %s", err) 
    } 

} 
관련 문제