Abrir arquivo e fazer a soma dos elementos

358 views
Skip to first unread message

Jéssika Queiroz

unread,
Jun 17, 2013, 10:05:43 AM6/17/13
to golang...@googlegroups.com
  Oi, realizei o seguinte programa, para abrir um arquivo txt, e fazer a soma dos valores dentro dele:

package main

import ( 
"fmt"
"io/ioutil"; 
  )


func main() {
contents,erro := ioutil.ReadFile("numeros.txt")
fmt.Printf(string(contents)) 

var numero = contents
var x int = int(numero)
soma := 0
if erro == nil{
soma=soma+x
}
fmt.Printf ("Soma: %d", soma)
ioutil.WriteFile("filename", contents, 0x777)
 }





Porém há um erro na transformação do inteiro para string, e não consigo pensar em outra forma de fazer essa soma. O arquivo "numeros.txt"  apresenta apenas 10 algarismos, sendo números naturais. Espero que possam me ajudar, obrigada!

Francisco Dalla Rosa Soares

unread,
Jun 17, 2013, 11:17:39 AM6/17/13
to golang...@googlegroups.com

import strings

strings.Atoi(numero)

se eu nao estiver enganado

2013/06/18 0:00 "Jéssika Queiroz" <jessika.quei...@gmail.com>:
--
 
---
Você está recebendo esta mensagem porque se inscreveu no grupo "Golang Brasil" dos Grupos do Google.
Para cancelar a inscrição neste grupo e parar de receber seus e-mails, envie um e-mail para golang-brasi...@googlegroups.com.
Para obter mais opções, acesse https://groups.google.com/groups/opt_out.
 
 

Abner

unread,
Jun 17, 2013, 4:31:35 PM6/17/13
to golang...@googlegroups.com
eu fiz assim:

package main

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


func main() {
contents,erro := ioutil.ReadFile("numeros.txt")

if (erro != nil){
fmt.Println(erro)
}
fmt.Printf(string(contents))

numeros := strings.Split(string(contents), " ")
soma := 0

for i := 0; i < len(numeros); i++ {
valor, _ := strconv.Atoi(numeros[i])
soma = soma + valor
}

fmt.Println ("Soma: ", soma)
}

ioutil.ReadFile() retorna um array com todo conteúdo do arquivo, a
função strings.Split() cria um slice de slices separando cada token da
string (no caso usando " " como separador, se os números estiverem
cada um em uma linha tem que usar "\n" acho) e strconv.Atoi()
transforma cada um dos tokens em int.


2013/6/17 Francisco Dalla Rosa Soares <dall...@gmail.com>:

Francisco Dalla Rosa Soares

unread,
Jun 17, 2013, 11:27:33 PM6/17/13
to golang...@googlegroups.com
Abner,

ah! exato! tava no transito e escrevi correndo entao me enganei! strconv!


2013/6/18 Abner <abn...@gmail.com>

Jéssika Queiroz

unread,
Jun 19, 2013, 8:22:28 AM6/19/13
to golang...@googlegroups.com
  Compilei esse programa que me mandou Abner, e ainda assim a soma dá 0.

Daniel Ortiz Pereira da Silva

unread,
Jun 19, 2013, 8:41:04 AM6/19/13
to golang...@googlegroups.com
Poste o conteudo do seu arquivo "numeros.txt"

Jéssika Queiroz

unread,
Jun 19, 2013, 8:48:03 AM6/19/13
to golang...@googlegroups.com
o conteúdo do arquivo é:
1
2
3
4
5
6
7
8
9
10

Abner

unread,
Jun 19, 2013, 8:49:51 AM6/19/13
to golang...@googlegroups.com
então vc tem que usar \n como separator na função Split():

numeros := strings.Split(string(contents), " \n")

2013/6/19 Jéssika Queiroz <jessika.quei...@gmail.com>:

Jéssika Queiroz

unread,
Jun 19, 2013, 8:57:18 AM6/19/13
to golang...@googlegroups.com
já usei e ainda não deu certo :S

Jéssika Queiroz

unread,
Jun 19, 2013, 9:01:09 AM6/19/13
to golang...@googlegroups.com
 Ontem eu tinha feito esse:

package main

import (
"fmt"
"log"
"os"
)

func main() {
file, erro := os.Open("numeros.txt") 
if erro != nil {
log.Fatal(erro)
}
data := make([]byte, 50)  //cria um vetor com espaco para 100 caracteres
count, erro := file.Read(data)
if erro != nil {
log.Fatal(erro)
}
fmt.Printf("Sao %d bytes: %s", count, data[:count])   //abre arquivo
soma := 0 
var x byte = byte(soma)
if erro == nil{
for i:=0; i<10; i++{
x = x + data[:i]
}
}
fmt.Printf ("Soma: %d", x)

ai o erro dado era: que não se pode misturar o tipo byte com []byte

talvez facilite, porque ai seria só transformar todos em inteiros, ou todos em byte
Message has been deleted

Abner

unread,
Jun 19, 2013, 10:58:55 AM6/19/13
to golang...@googlegroups.com
não sei porque ta dando errado. acho que deve ser algo do numeros.txt,
tem exatamente um número por linha? tem espaço depois do número ou só
\n? tem como voce enviar anexado o numeros.txt ?

2013/6/19 Jéssika Queiroz <jessika.quei...@gmail.com>:
> Hoje estou ajustando o meu programa anterior com o que me mandaram, e ficou
> assim:
>
> package main
>
> import (
> "fmt"
> "strings"
> "io/ioutil"
> "strconv"
> )
>
>
> func main() {
> contents,erro := ioutil.ReadFile("numeros.txt")
> if (erro != nil){
> fmt.Println(erro)
> }
> fmt.Printf(string(contents))
>
> numeros := strings.Split(string(contents), "\n") //cria um slice de slices
> separando cada token da string
> soma := 0
> if erro == nil{
> for i := 0; i < len(numeros); i++ {
> valor, _ := strconv.Atoi(numeros[i]) //transforma cada um dos tokens em
> int
> soma = soma + valor
> }
> fmt.Printf ("Soma: %d", soma)
> }
> ioutil.WriteFile("filename", contents, 0x777)
> }
>
>
> e ainda assim a soma é igual 0

Jéssika Queiroz

unread,
Jun 19, 2013, 11:13:10 AM6/19/13
to golang...@googlegroups.com

anexei o arquivo, tinha um enter depois do número 10. Agora mudei, e o valor da soma está sendo 10
 
numeros.txt

Jéssika Queiroz

unread,
Jun 19, 2013, 11:16:00 AM6/19/13
to golang...@googlegroups.com

tinha um enter no ultimo numero, já retirei
mas mesmo assim a soma agora tem valor 10 
numeros.txt

Jéssika Queiroz

unread,
Jun 19, 2013, 11:28:47 AM6/19/13
to golang...@googlegroups.com
 Olha, esse quase deu certo, eu retirei o "\n" da seguinte linha: numeros := strings.Split(string(contents), "")
ele faz a soma, mas dá 46, acho que ele considera o número 10, como sendo 1 e 0
neew.go

Abner

unread,
Jun 19, 2013, 11:29:22 AM6/19/13
to golang...@googlegroups.com
esse arquivo de números, foi criado no windows e ai o caractere de
nova linha é o \r\n, coloca isso como separator na função Split() que
da certo.

2013/6/19 Jéssika Queiroz <jessika.quei...@gmail.com>:
>
>> tinha um enter no ultimo numero, já retirei
>
> mas mesmo assim a soma agora tem valor 10
>

Jéssika Queiroz

unread,
Jun 19, 2013, 9:39:06 PM6/19/13
to golang...@googlegroups.com
colocando esse "\r\n"  ele vai conseguir somar o 10 também?
vou tentar, obrigada

Fabio Kaminski

unread,
Jun 19, 2013, 11:00:13 PM6/19/13
to golang...@googlegroups.com
Ando meio afastado de GO..

Mas a melhor pedida pra qualquer parser é fazer um loop geral lendo todo o payload
e processar caracter a caracter.. acumula em uma variável qualquer (byte[] ?), sendo um payload temporário
até achar a quebra de linha.. então converte para int e adiciona a um array fora do escopo(fora do loop) de ints
no final soma todos os itens do array..  ou então uma versão sem o array de ints.. com apenas um int acumulador
onde a soma ja é efetuada diretamente.. (essa lógica da pra aplicar a qualquer linguagem)

Outra também é usar regexp.. o trabalho fico no construir  expressão regexp.. 
mas o formato acima serve pra qualquer parser..

Na dúvida da uma olhada nos fontes das libs do go.. em qualquer lib que tenha um parser de texto.. 
ex. json

quando comecei a brincar com Go lá em 2009 só tinha as libs da linguagem pra se inspirar e aprender melhor..
outra que os caras que escreveram as libs são feras (princ. o Rob Pike) em design de apis..  então tem sempre o que aprender por la.. 

Se for der dor de cabeça e não der certo, me avisa que eu monto pra voce, pra desenferrujar o go 
(mas tenta primeiro neh.. :)


2013/6/20 Jéssika Queiroz <jessika.quei...@gmail.com>
colocando esse "\r\n"  ele vai conseguir somar o 10 também?
vou tentar, obrigada

--

Fabio Kaminski

unread,
Jun 19, 2013, 11:18:25 PM6/19/13
to golang...@googlegroups.com
Ah.. esquecendo..  e ainda tem uma versão go pura pra aplicar a esse problema :)
da pra usar os channels do go pra resolver isso ai.. 

nesse caso gera um produtor de dados de um lado que iria ler e enviar o arquivo
e um consumidor do outro lado do channel que vai consumir esse payload  converter e acumular o total.. 

essa versão do algorítmo seria o mais go possível..  tinha um tutorial.. sieve of erastostenes sobre esse tópico que deve ajudar..  esse algorítmo deve ser o mais compacto e legivel dos 3.. 



2013/6/20 Fabio Kaminski <fabiok...@gmail.com>

Jéssika Queiroz

unread,
Jun 20, 2013, 8:21:39 AM6/20/13
to golang...@googlegroups.com
Já deu certo, colocando o \r\n, muito obrigada! :D
Message has been deleted

Jéssika Queiroz

unread,
Jun 20, 2013, 11:13:36 AM6/20/13
to golang...@googlegroups.com

ai estão os dois arquivos, agora preciso gravar a sequencia de numeros, a soma e a media em txt

usei o comando> ioutil.WriteFile("filename", contents, 0x777)    
porém só grava os numeros
media.go
numeros.txt

Fabio Kaminski

unread,
Jun 20, 2013, 3:20:04 PM6/20/13
to golang...@googlegroups.com
No seu código veja que você usa a variável contents pra guardar o conteúdo do arquivo
e que a soma do total é feita na variavel numeros.. e depois voce esta salvando a media na variavel média.. 

assim se voce apenas pegar a variavel contents e salvar em um arquivo, estará salvando o mesmo conteudo que leu do arquivo na operaçao:  

contents, erro := ioutil.ReadFile("numeros.txt") /

então, voce pode criar uma nova variavel.. vamos dizer "output"
onde voce irá acrescentar a essa nova variável, o conteudo da variável contents + a variavel soma + a variável média
não esquecendo que contents esta no formato bytes, soma é um int e média também

naquela operação por exemplo: 
fmt.Printf(string(contents))  < -- voce converteu o contents para string

pra facilitar a conversão eu aconselho a criar um bytebuffer.. e ir adicionando as variáveis dos tipos distintos
nesse buffer.. depois é só salvar o conteudo do buffer... ex:

output := new Buffer(contents)
output.WriteString("soma:")
output.Write(soma)
output.WriteString("\nmedia:")
output.Write(media)

ioutil.WriteFile("filename", output.Bytes(), 0x777)

acho que outra forma seria usando o Fprintf: (que é mais recomendado quando se sabe de antemao o conteudo e é menos dinamico -> seu caso)


nesse caso não precisa usar uma variavel intermediária para juntar os resultados.. basta gravar direto

que seria algo como:

len, err := fmt.Fprintf(os.Stdout, "%s\nsoma:%d\nmedia:%d", contents, soma, media)  // vai imprimir no console

ou

file, err := os.OpenFile("output.txt", O_WRITE, 0666)

len, err := fmt.Fprintf(file, "%s\nsoma:%d\nmedia:%d", contents, soma, media)  // vai imprimir no arquivo output.txt

(acho que voce irá preferir esse método.. :)

nota: não testei.. então pode haver erros que precisam de correção.. a ideia é dar uma idéia geral :/


2013/6/20 Jéssika Queiroz <jessika.quei...@gmail.com>

ai estão os dois arquivos, agora preciso gravar a sequencia de numeros, a soma e a media em txt

usei o comando> ioutil.WriteFile("filename", contents, 0x777)    
porém só grava os numeros

--

Jéssika Queiroz

unread,
Jun 21, 2013, 8:57:18 AM6/21/13
to golang...@googlegroups.com
fazendo com essa parte de Buffer ai, dá o seguinte erro: unexpected name, expecting semicolon or newline or }
e esse erro se refere a primeira linha onde tem o output (output := new Buffer...) 

já pelo outro método, falta uma especificação para O_WRITE
eu não sei o que é, devo trocar pelo nome do arquivo, ou coisa assim?

Jéssika Queiroz

unread,
Jun 21, 2013, 10:14:07 AM6/21/13
to golang...@googlegroups.com
 Fazendo desse jeito, dá erro pois o len é um int, e tem que ser transformado para byte[]
eu não entendo por que, e nem como faz essa transformação
media2.go

Fabio Kaminski

unread,
Jun 21, 2013, 9:05:40 PM6/21/13
to golang...@googlegroups.com
Dessa vez eu resolvi fazer uma versão aqui de um código para resolver esse problema.. 
mas está bem diferente do código original :)

enfim.. roda, dá uma olhada e vê o que voce compreende dele.. e me avisa qualquer problema..


2013/6/21 Jéssika Queiroz <jessika.quei...@gmail.com>
 Fazendo desse jeito, dá erro pois o len é um int, e tem que ser transformado para byte[]
eu não entendo por que, e nem como faz essa transformação

--
media.go
Message has been deleted

Jéssika Queiroz

unread,
Jun 23, 2013, 8:24:53 PM6/23/13
to golang...@googlegroups.com
não entendi direito o que fez, pois há comandos que não conheço, mas consegui converter o int para []byte, e já me ajudou um pouco.
 Obrigada

Fabio Kaminski

unread,
Jun 24, 2013, 10:15:48 PM6/24/13
to golang...@googlegroups.com
ok, mas nesse caso ai, o arquivo de saida "resultados" vai ter só um inteiro que é a soma, no arquivo
e pelo que entendi vc quer no arquivo resultante.. os numeros, a soma e a média.. 
se voce rodar aquela versão que lhe passei é isso com sai.. 

outra coisa é voce ter cuidado nas conversões pois no arquivo texto pode sair algo diferente do que vc quer..
por exemplo.. voce pode converter o valor do inteiro diretamente para o respectivo em bytes.. só que o que vc esta esperando na saida é um valor numerico em texto, na codificação ascii.. assim teria que converter o inteiro pra string primeiro e depois pegar os bytes direto da string.. no go acho que basta voce fazer um casting normal da variavel para []byte.. 

foi exatamente pelo motivo de que o arquivo de saida ter de ser composto (numeros+soma+media) que te enviei aquela versão , pois com utilizando buffers de bytes/streams simplifica a composição de valores sejam eles de que tipos forem
e depois é só pegar o resultado da memória e gravar no arquivo de saida..

da forma como você esta fazendo, a solução seria abrir o arquivo de saida em modo append
e então efetuar o write pra cada valor..  mas descartei essa versão ao implementar a solução para o seu problema 
pois isso é bem custoso a nivel de sistema, pois vc vai abrir um file handle várias vezes sendo que a operação pode ser atomica e ocorrer uma vez só..

Agora se vc ta seguindo uma linha de raciocinio, e aprendendo com o código que montou, vai em frente! é assim que a gente vai pegando muitas sutilezas e aprendendo bastante de uma forma que a gente nunca esquece :)

Meu conselho é que voce tenha o go na versão codigo fonte em sua máquina..e va consultando os fontes da própria lib do go pra ver como eles fazem.. é a melhor forma de aprender, até pq vc chega tambem na forma de pensar de quem faz... 
o estilo dos pacotes lib no diretorio pkg do go são excelentes e transmitem além de como trabalhar com a linguagem uma forma bem sofisticada de pensar na solução de problemas cotidianos

lhe desejo sorte e força de vontade! abraços


2013/6/24 Jéssika Queiroz <jessika.quei...@gmail.com>
não entendi direito o que fez, pois há comandos que não conheço, mas consegui converter o int para []byte, e já me ajudou um pouco.
 Obrigada

--

Jéssika Queiroz

unread,
Jun 25, 2013, 8:12:26 AM6/25/13
to golang...@googlegroups.com
  Ah sim, entendi. Muito obrigada pela ajuda

Jéssika Queiroz

unread,
Jun 25, 2013, 8:15:16 AM6/25/13
to golang...@googlegroups.com
ah, onde consigo esse código fonte de Go? no próprio site goland tem?

Fabio Kaminski

unread,
Jun 25, 2013, 1:23:35 PM6/25/13
to golang...@googlegroups.com
Oi Jéssica

tem que ter o controlador de versões mercurial(no caso da golang) pra baixar o repositorio fonte
assumindo que vc esta usando um windows baixa um dos dois arquivos (windows 32 ou 64 bit):

se o seu windows é 64 bit:

se o seu windows é 32 bit:

na dúvida instala o de 32 bits pois funciona para ambos.

depois que instalar voce abre o seu console/prompt,  entra em algum diretório onde vc queira guardar os fontes
e manda esse comando:


As instruções estão nesse site da golang:


e pronto..  voce tambem tem a possibilidade de sempre atualizar o fonte digitando:

$ hg pull
e depois que baixar o update:
$ hg update release

e tambem pode compilar o fonte criando o compilador Go direto a partir da ultima atualização.. 
(se for windows o processo é um pouquinho mais dolorido.. tem que usar cygwin e afins)

depois que baixar o fonte.. entra no diretorio:
src/pkg/  (dentro do diretorio clonado do fonte do go)

e ali estão os fontes de todas as bibliotecas standard usadas ao se criar
os programas em Go.. ali existem várias formas de se resolver certas situações
usando a pŕopria linguagem.. 

Quando a linguagem é recente e não existem tantas formas de se aprender.. o aprendizado tem que ser ao modo hacker mesmo.. lendo os códigos fontes existentes :)


2013/6/25 Jéssika Queiroz <jessika.quei...@gmail.com>
ah, onde consigo esse código fonte de Go? no próprio site goland tem?

--

Francisco Dalla Rosa Soares

unread,
Jun 25, 2013, 9:18:41 PM6/25/13
to golang...@googlegroups.com
voce tambem pode baixar o pacote do codigo fonte da ultima versao estavel:


a lista de arquivos pode ser encontrada em:





2013/6/26 Fabio Kaminski <fabiok...@gmail.com>

Jéssika Queiroz

unread,
Jun 26, 2013, 9:14:38 AM6/26/13
to golang...@googlegroups.com
aham, muito obrigada!

Paulo Moises

unread,
Jul 18, 2013, 3:55:01 PM7/18/13
to golang...@googlegroups.com

   package main
    import (
    "fmt"
    "os"
    "strings"
    "strconv"
    )
   
    func main() {
    file, err := os.Open("numeros")
     if err == nil {
     stat, err := file.Stat()
      if err == nil {
      lines := make([]byte, stat.Size())
      file.Read(lines)
      numeros := strings.Split(string(lines),"\n")
      soma := 0
           for _, v := range(numeros) {
              vv, _ := strconv.Atoi(v)
              soma += vv
           }
           fmt.Println(soma)
      }
      file.Close()
     }
    }
Em segunda-feira, 17 de junho de 2013 11h05min43s UTC-3, Jéssika Queiroz escreveu:
  Oi, realizei o seguinte programa, para abrir um arquivo txt, e fazer a soma dos valores dentro dele:

package main

import ( 
"fmt"
"io/ioutil"; 
  )


func main() {
contents,erro := ioutil.ReadFile("numeros.txt")
fmt.Printf(string(contents)) 

var numero = contents
var x int = int(numero)
soma := 0
if erro == nil{
soma=soma+x
}
fmt.Printf ("Soma: %d", soma)
ioutil.WriteFile("filename", contents, 0x777)
 }





Porém há um erro na transformação do inteiro para string, e não consigo pensar em outra forma de fazer essa soma. O arquivo "numeros.txt"  apresenta apenas 10 algarismos, sendo números naturais. Espero que possam me ajudar, obrigada!

Herbert Fischer

unread,
Jul 23, 2013, 9:34:30 PM7/23/13
to golang...@googlegroups.com
Reply all
Reply to author
Forward
0 new messages