pegar string

Fórum sobre a linguagem CA-Clipper.

Moderador: Moderadores

claudiocjr
Usuário Nível 1
Usuário Nível 1
Mensagens: 29
Registrado em: 03 Mai 2005 10:07

pegar string

Mensagem por claudiocjr »

Ola Pessoal

Tenho um arquivo texto meio grandinho mais ou menos assim

<DADOS> <EMITENTE CNPJ="0000000000" INSC.ESTADUAL="0000000"/>
<Itens Nota><Sequencia = "1" Descricao="sem descricao">
<Itens Nota<>Sequencia = "2" Descricao="teste"/>

Como fasso para pegar os valores que estao entre as ASPAS?

Obs : Os valores que estão entre as aspas não possuem tamanhos
fixos


Grato Claudio
Dudu_XBase
Membro Master
Membro Master
Mensagens: 1071
Registrado em: 25 Ago 2003 16:55

Mensagem por Dudu_XBase »

Claúdio Bom Dia ....
Vc deve fazer uso da função at().
// sintaxe
http://www.clipx.net/ng/clguide/ngf688.php

Não sei como vc esta processando esse arquivo txt.

Código: Selecionar todos

  Por exemplo para pegar o CNPJ:
   
  
  cTemp := "TESTE"
  aTemp := {}
  aadd (aTemp, {"TEXTO","C",300,0})
  dbcreate (cTemp, aTemp)
  dbusearea ( .t.,,cTemp,, .f., .f.)
  append from seuarqui.txt SDF // jogo os dados do seu txt no dbf...
 
  dbgotop()
  While ! eof()
      // valor a ser procurado
      cLoc := "EMITENTE CNPJ="
      // para localizar a posição inicial
      nposINI := at(cLoc,TEXTO)+len(cLoc)+1
      // para localizar a posição final
      nposFim := at(´"´,substr(TEXTO,nposINI,len(TEXTO))   
      // localizado as posições eu atribuo o conteúdo a uma var
      if nposFIM > 0
        cCNPJ := substr(TEXTO,nposINI,nposFIM-nposINI)        
      endif


      dbskip()
  enddo

  


Espero q vc entendeu esse principio.
Solicito que realize seus testes e poste-nos seu retorno.


________________________________________________________________________________________________________
(Aow Saudade) Clipper 5.2e, Blinker 7, RDD SIXNSX, DBFCDX /Xharbour 1.0, Rdd Mediator (Mysql) Free , RDD Sqlrdd (Sql Server) Comercial
(Hoje) C# Python Sql Server e Oracle




claudiocjr
Usuário Nível 1
Usuário Nível 1
Mensagens: 29
Registrado em: 03 Mai 2005 10:07

Mensagem por claudiocjr »

Grato pela sua colaboração Dudu-xBase

Mas não sei se estou fazendo certo, pois pelo
que entendo do comando Append From ele
copia o TXT para DBF quando a os Delimitadores no
final de cada linha, no meu caso não há e o comando
append copia uma linha de 255 no maximo.

Caso exista outra maneira, ou tiver uma solução para mim
ficaria eternamente grato, pois estou necessitando muito disso.

SDS

Claudio
Dudu_XBase
Membro Master
Membro Master
Mensagens: 1071
Registrado em: 25 Ago 2003 16:55

Mensagem por Dudu_XBase »

Aumente o campo do dbf para o tamanho q vc irá usar.
Eu processo uns arquivos com mais de 400 posições assim e até agora nunca tive problemas.


________________________________________________________________________________________________________
(Aow Saudade) Clipper 5.2e, Blinker 7, RDD SIXNSX, DBFCDX /Xharbour 1.0, Rdd Mediator (Mysql) Free , RDD Sqlrdd (Sql Server) Comercial
(Hoje) C# Python Sql Server e Oracle




claudiocjr
Usuário Nível 1
Usuário Nível 1
Mensagens: 29
Registrado em: 03 Mai 2005 10:07

pegar string

Mensagem por claudiocjr »

Grato mais uma vez pela sua colaboração

Vou tentar fazer varios campos, com o maximo de
caracteres cada, pois este arquivo é um XML, e é
de um tamanho meio grande.

Dudu por um acaso vc. não sabe se a possibilidade de
ler o arquivo texto e já verificando as strings ?

SDS

Claudio
Dudu_XBase
Membro Master
Membro Master
Mensagens: 1071
Registrado em: 25 Ago 2003 16:55

Mensagem por Dudu_XBase »



________________________________________________________________________________________________________
(Aow Saudade) Clipper 5.2e, Blinker 7, RDD SIXNSX, DBFCDX /Xharbour 1.0, Rdd Mediator (Mysql) Free , RDD Sqlrdd (Sql Server) Comercial
(Hoje) C# Python Sql Server e Oracle




claudiocjr
Usuário Nível 1
Usuário Nível 1
Mensagens: 29
Registrado em: 03 Mai 2005 10:07

pegar string

Mensagem por claudiocjr »

Já tentei usar aquela que pega a string diretamento do arquivo
texto, mas não sei o que a de errado, pois em minha aplicação
não funciona.

blz

Claudio
Avatar do usuário
Maligno
Membro Master
Membro Master
Mensagens: 6398
Registrado em: 06 Jul 2004 01:40
Localização: Londrina/PR

Re: pegar string

Mensagem por Maligno »

claudiocjr escreveu:mas não sei o que a de errado, pois em minha aplicação não funciona.
Se ainda não resolveu o problema (não tinha visto esta thread), poste aqui a parte do código que não funcionou. Mas na thread que lhe indicaram eu postei uma forma de pegar string que não tem erro: pegar (o código é simples) e analisar linha por linha, até o fim do arquivo.

[]'s
Maligno
http://www.buzinello.com/prg
claudiocjr
Usuário Nível 1
Usuário Nível 1
Mensagens: 29
Registrado em: 03 Mai 2005 10:07

pegar string

Mensagem por claudiocjr »

Ola
Primeiramente obrigado pela sua colaboração

O Problema é que o sistema não passa do while
para começar o processo e tambem não trato o erro
de abertura do codigo, tentei de varias maneiras,
sera que não é a passagem de parametros para
a abertura do arquivo ?


t+

Claudio
Avatar do usuário
Maligno
Membro Master
Membro Master
Mensagens: 6398
Registrado em: 06 Jul 2004 01:40
Localização: Londrina/PR

Re: pegar string

Mensagem por Maligno »

claudiocjr escreveu:O Problema é que o sistema não passa do while
para começar o processo e tambem não trato o erro
de abertura do codigo, tentei de varias maneiras,
sera que não é a passagem de parametros para
a abertura do arquivo ?
Não adianta. Se você não mostrar o código problemático (exatamente) como ele é, não dá para dizer nada.

[]'s
Maligno
http://www.buzinello.com/prg
claudiocjr
Usuário Nível 1
Usuário Nível 1
Mensagens: 29
Registrado em: 03 Mai 2005 10:07

pegar string

Mensagem por claudiocjr »

Blz

Como não estava funcionando, apaguei o código,
mas vou refazer e assim que estiver lhe mando

t+

Claudio
Avatar do usuário
Maligno
Membro Master
Membro Master
Mensagens: 6398
Registrado em: 06 Jul 2004 01:40
Localização: Londrina/PR

Re: pegar string

Mensagem por Maligno »

Como não estava funcionando, apaguei o código,
mas vou refazer e assim que estiver lhe mando
Já que vai refazer, vou lhe dar uma dica que vai tornar sua tarefa bem mais fácil. Tudo o que fazemos em programação é PROBLEMA e não dá pra fugir disso. Mas o "pulo-do-gato" pra conseguir se dar bem nessa área é saber resolver os problemas de forma eficaz e, principalmente, simples. O truque é resolver o problema dividindo-o em problemas menores, e resolvê-los um a um. Daí vem o termo abstração. A forma "canônica" de fazer isso é chamada de programação "top-down", ou seja, de cima pra baixo. Quando chegar ao nível mais inferior, acabou o problema principal, que gerou os menores. Essa discussão é filosófica e não cabe numa simples thread. Infelizmente os "cursos" que se encontram na Internet tratam apenas dos aspectos mais imediatistas e ignoram as metodologias. É sempre assim: as matérias "chatas" são postas de lado para que se possa privilegiar o lado mais "palpável" e, claro, mais excitante da programação. Aí é que os problemas do programador realmente começam.

Mas vou tentar lhe dar um exemplo simples, com base no problema que você quer resolver. A sua necessidade é pesquisar por uma string qualquer num arquivo texto. Como já disseram, você pode importar tudo para um DBF e pesquisar os campos. Eu já disse e repito que é muito melhor fazer pela leitura direta do arquivo texto. Só não é mais fácil porquê isso envolve muito mais manipulação de string que o normal. Mas isso é coisa que você precisa saber. Quem trabalha com sistemas de informação precisa ser "cobra" em manipulação de strings. Do contrário, vai viver sofrendo com coisas pequenas. Então, não adianta ficar fugindo disso. Se não for um "malabarista" de strings, prepare-se e faça tudo para sê-lo.

Voltando ao problema principal: nada se faz bem feito sem metodologias apropriadas para o contexto que será abordado. No caso, como eu já disse, você precisa dividir o problema, criando uma abstração ou, como alguns costumam dizer, elevando o nível do problema, dividindo-o em problemas menores, de níveis mais baixos. Imagine (ou fantasie) uma solução ideal. Veja como fica simples:

Código: Selecionar todos

function PesqString(cArq,; // nome do arquivo alvo da pesquisa
                    cStr ; // string que se precisa procurar
                    )
if !AbreArq()
   // Não deu pra abrir: fim
   return
end
*
while .T.
   cLine := ReadText()
   if cLine = nil
      // Foi sinalizado que não há mais linhas
      exit
   end
   //
   // Neste ponto você tem o conteúdo de uma linha
   // Com o conhecimento que tem de manipulação de
   // strings, procure a string nesta linha e faça
   // o que tiver de ser feito. Se encontrou e não
   // precisar continuar, simplesmente retorne com
   // o resultado ou continue lendo até o fim. Vai
   // da sua necessidade.
   //
   cResult :=
end
Mais fácil que isso, impossível. Você abre o arquivo e lê linha por linha até o fim. A cada leitura, verifica se existe a string procurada. A cada iteração, cLine será checada. Se o conteúdo dela for NIL, estará sinalizado o fim do arquivo. Nada mais há para ser lido. Encerra-se o trabalho, devolvendo à rotina chamadora o resultado encontrado. A variável cResult é apenas ilustrativa.

Nessa etapa você já abstraiu o máximo que pôde e resolveu seu problema principal de maneira simples e muito eficiente. Aliás, note como a legibilidade melhora bastante. Nada daqueles emaranhados de códigos para atrapalhar. Fica perfeito desta forma.

Mas lembre-se de que a nossa intenção era dividir o problema principal. Isso já fizemos. Agora, na próxima etapa, temos de resolver os outros problemas menores, criados para resolver o problema principal.

De imediato pensamos na função AbreArq(). No Clipper já existe função para a abertura de arquivos. Será apenas o caso de substituirmos essa chamada pela função do próprio Clipper. Como na função já existe um parâmetro para o nome do arquivo, podemos usar:

Código: Selecionar todos

function PesqString(cArq,; // nome do arquivo alvo da pesquisa
                    cStr ; // string que se precisa procurar
                    )
local nHandle
if (nHandle := FOpen(cArq)) = -1
   return // retorne um indicador qualquer de erro
end
...
Agora a parte mais trabalhosa: precisamos ter a função ReadText() que faça o "trabalho sujo" e chato da leitura de linha por linha, sem se perder. É chato, é trabalhoso, mas se você tiver uma função dessas funcionando perfeitamente, você não só vai resolver esse seu problema, como muitos outros problemas semelhantes. Isso é que é legal na programação. Você constrói blocos de códigos e utiliza-os sempre que precisar, sem precisar alterar uma vírgula neles. Fiz uma adaptação da função que deixei na outra thread:

Código: Selecionar todos

#define _kSIZE 2048
#define _kEOL  Chr(13)+Chr(10)

static cBuff // o buffer de armazenamento
static lCont // se TRUE, o sistema só precisará continuar analisando
             // o buffer, que provavelmente, ainda deve conter dados

//------------------------------------------------------------------
function ReadText(nHandle)   // se nHandle=0, reinicialize o sistema
local nByts                  // bytes lidos na iteração
local cBuff := Space(_kSIZE) // buffer de armazenamento
local cRest := ""            // resto da leitura
local cLine                  // a linha recuperada do arquivo
local i                      // indexador
*
if nHandle = 0
   cBuff := Space(_kSIZE) // zerar o buffer
   lCont := .F.           // indicar um início de leitura do arquivo
   FSeek(nHandle,0)       // ajustar o ponteiro do arquivo no início
   return nil             // ok, sistema reinicializado
end
*
while lCont                                       .or.;
      (nByts := FRead(nHandle,@cBuff,_kSIZE)) > 0 .or.;
      !Empty(cRest)

   if !lCont
      cBuff := RTrim(cBuff)
      cBuff := cRest+cBuff
      cBuff += if(nByts=0 .and. Right(cBuff,2) != _kEOL, _kEOL, "")
   end
   *
   if (i := At(_kEOL,cBuff)) > 0
      cLine := Left(cBuff,i-1)   // a linha, sem o par CR/LF
      cBuff := SubStr(cBuff,i+2) // descartado CR/LF do buffer
      lcont := .T.               // sinalizar a continuação
      //
      // Retornar a linha atualmente focalizada
      return cLine
   end
   cRest := cBuff
   cBuff := Space(_kSIZE)
   lCont := .F. // neste ponto não há continuidade da leitura do
                // buffer anteriormente carregado; é preciso ler
                // do arquivo, como se estivessemos começando.
end
//
// Se chegou a esse ponto, não há mais o que ser lido no arquivo
return nil

NOTA: Esta função deve residir em arquivo próprio, já que ela é uma ferramenta de abstração e contém variáveis estáticas. É um componente reutilizável.

Com relação a leitura do arquivo, temos agora a solução completa. Só ficará faltando você inserir o seu código de pesquisa dentro da linha. Já preparado, eis o código final, em alto nível:

Código: Selecionar todos

function PesqString(cStr,; // string a ser procurada
                    cArq ; // nome do arquivo alvo da pesquisa
                    )
local nHandle
if (nHandle := FOpen(cArq)) = -1
   return // retorne um indicador qualquer de erro
end
*
ReadText(0) // inicializa nosso sistema de leitura
while .T.
   cLine := ReadText(nHandle)
   if cLine = nil
      * Fim de leitura: faça o que achar melhor
   end
   //
   // Código da pesquisa dentro da linha
   cResult := ...
end
Abordei o assunto de maneira bem simples. Mas se ainda tiver alguma dúvida, é só enviar outra mensagem (não em private, por favor) na thread.

E só mais um detalhe: não testei a função ReadText(). Tenho meu próprio sub-sistema de manipulação de arquivos texto, que é bem mais flexível que isso. Essa função eu tinha feito para aquela outra thread e só adaptei para você. Se der pau, tente consertar. Se tiver problema com isso, volte à esta thread novamente, para podermos ajudá-lo.

[]'s
Maligno
http://www.buzinello.com/prg
Responder