EOF e quebra de linha Windows && Linux

1. EOF e quebra de linha Windows && Linux

Fabiano Vasconcelos
NewWave

(usa Ubuntu)

Enviado em 15/09/2014 - 12:44h

Boa tarde, experts!

Estou a desenvolver uma aplicaçãozinha em C++, mas esbarrei em uma dúvida, que por sinal já googlei e nada.
Todo mundo aqui sabe que se nós abrirmos um arquivo texto plano, feito no bloco de notas do windows, no linux, ele não manterá a formatação original, pelo menos na quebra de linha. Aparecerá um quadrado no lugar do caractere de quebra de linha. Isso significa que o win e o linux usam caracteres diferentes para quebrar a linha.
Acontece que eu preciso analisar um txt feito no win numa aplicação minha compilada e rodada no linux. Obviamente, na hora que eu esbarrar com a quebra de linha, em vez de ele tratar esta como quebra de linha (\n) ele não vai achar o caratere usado no linux para tal e o programa vai se comportar de forma insperada.
A pergunta é: qual o caratere usado pelo windows para quebra de linha para que eu possa implementar a função de forma correta? Qual o seu código?
Aproveitando, EOF em linux e win são a mesma coisa?

Obrigado a todos.


  


2. Re: EOF e quebra de linha Windows && Linux

euteste da silva
foxbit3r

(usa Solaris)

Enviado em 15/09/2014 - 15:46h

Colega,
Para você poder analisar o seu aquivo txt você pode fazer o seguinte.

dos2unix arquivo.txt
cat arquivo.txt


No Windows a quebra de linha costuma ser

\n\r



3. Re: EOF e quebra de linha Windows && Linux

Paulo
paulo1205

(usa Ubuntu)

Enviado em 15/09/2014 - 15:47h

NewWave escreveu:

Boa tarde, experts!

Estou a desenvolver uma aplicaçãozinha em C++, mas esbarrei em uma dúvida, que por sinal já googlei e nada.
Todo mundo aqui sabe que se nós abrirmos um arquivo texto plano, feito no bloco de notas do windows, no linux, ele não manterá a formatação original, pelo menos na quebra de linha. Aparecerá um quadrado no lugar do caractere de quebra de linha. Isso significa que o win e o linux usam caracteres diferentes para quebrar a linha.


Mais do que simplesmente caracteres diferentes, são convenções diferentes: o mundo POSIX/UNIX/Linux usa apenas um caráter, que é aquele indicado no ASCII como line feed (ou LF, correspondente em C a '\n'), enquanto o mundo Microsoft usa dois caracteres combinados, que são sempre o ASCII carriage return (ou CR, correspondente em C a '\r') seguido pelo LF.

Esse negócio de "quadrado" geralmente não acontece no Linux. Acho que você provavelmente está confundindo com o que o Notepad do Windows mostra quando você tenta abrir um arquivo de texto gerado no Linux. Se for o caso, você trocou o sentido da observação.

Acontece que eu preciso analisar um txt feito no win numa aplicação minha compilada e rodada no linux. Obviamente, na hora que eu esbarrar com a quebra de linha, em vez de ele tratar esta como quebra de linha (\n) ele não vai achar o caratere usado no linux para tal e o programa vai se comportar de forma insperada.


Errado. Ele vai achar o LF que vem logo depois do CR, e vai começar a linha nova exatamente no mesmo ponto em que o Windows começaria. A diferença é que pode haver um CR sobrando no final de cada linha. Esse CR geralmente é categorizado como caráter de espaçamento (ver função isblank()), e não provoca efeito visível se você simplesmente reproduzir o conteúdo do arquivo num terminal de texto ou impressora (se tudo estver configurado corretamente, claro).

A pergunta é: qual o caratere usado pelo windows para quebra de linha para que eu possa implementar a função de forma correta? Qual o seu código?


Está respondido acima.

Aproveitando, EOF em linux e win são a mesma coisa?


EOF não é um caráter, mas um código de sinalização de erro devolvido por várias funções da biblioteca de I/O. O símbolo EOF geralmente tem o valor inteiro -1, que é diferente do valor de caráter com sinal -1, ainda que os dois sejam silenciosamente convertidos de caráter para inteiro ou vice-versa, se você não tomar os devidos cuidados, mas você não precisa -- nem deve! -- se preocupar com o valor por trás do símbolo: use sempre o símbolo.

Obrigado a todos.


PS: O cuidado que você tem de ter para não perder a sinalização de EOF, confundindo-a com um caráter qualquer, é prestar atenção ao fato de que as funções que fazem entrada e saída (mas especialmente entrada) de caracteres individuais sempre devolvem valores inteiros, e não um do tipo char. Você, por conseguinte, tem de usar também variáveis inteiras na hora de receber tais valores, e só tentar extrair um caráter de dentro delas depois de ter certeza de que o valor retornado não é EOF.

PS2: Eu acho muito pouco provável que não haja explicações bem melhores do que a minha na Internet. Se você procurou no Google e não encontrou resposta, seus termos de pesquisa não devem ter sido muito bons.


4. Re: EOF e quebra de linha Windows && Linux

Fabiano Vasconcelos
NewWave

(usa Ubuntu)

Enviado em 15/09/2014 - 19:53h

Olá, amigo!

Em primeiro lugar, obrigado por se preocupar em responder. Muito agradecido.
Em seguida, tenho que dizer que na tua resposta deu um erro aqui na página e apareceu tudo quando foi de código HTML & seus amigos, deixando o post uma bagunça. Mas sem problemas, eu consegui ler tudo no email. Mas se você puder postar de novo, pra ver se fica pra posteridade, um tanto melhor.

Mais do que simplesmente caracteres diferentes, são convenções diferentes: o mundo POSIX/UNIX/Linux usa apenas um caráter, que é aquele indicado no ASCII como line feed (ou LF, correspondente em C a '\n'), enquanto o mundo Microsoft usa dois caracteres combinados, que são sempre o ASCII carriage return (ou CR, correspondente em C a '\r') seguido pelo LF.


Isso já responde a minha pergunta.

Esse negócio de "quadrado" geralmente não acontece no Linux. Acho que você provavelmente está confundindo com o que o Notepad do Windows mostra quando você tenta abrir um arquivo de texto gerado no Linux. Se for o caso, você trocou o sentido da observação


Tem razão! Na pressa de escrever a dúvida, lembrava que acontecia um fenômeno como esse, mas acabei confundindo os sentidos. Desculpe.

Errado. Ele vai achar o LF que vem logo depois do CR, e vai começar a linha nova exatamente no mesmo ponto em que o Windows começaria. A diferença é que pode haver um CR sobrando no final de cada linha. Esse CR geralmente é categorizado como caráter de espaçamento (ver função isblank()), e não provoca efeito visível se você simplesmente reproduzir o conteúdo do arquivo num terminal de texto ou impressora (se tudo estver configurado corretamente, claro).


Estou avisado. Resta saber como eu vou lidar com isso na prática.

EOF não é um caráter, mas um código de sinalização de erro devolvido por várias funções da biblioteca de I/O. O símbolo EOF geralmente tem o valor inteiro -1, que é diferente do valor de caráter com sinal -1, ainda que os dois sejam silenciosamente convertidos de caráter para inteiro ou vice-versa, se você não tomar os devidos cuidados, mas você não precisa -- nem deve! -- se preocupar com o valor por trás do símbolo: use sempre o símbolo.

Obrigado a todos.


PS: O cuidado que você tem de ter para não perder a sinalização de EOF, confundindo-a com um caráter qualquer, é prestar atenção ao fato de que as funções que fazem entrada e saída (mas especialmente entrada) de caracteres individuais sempre devolvem valores inteiros, e não um do tipo char. Você, por conseguinte, tem de usar também variáveis inteiras na hora de receber tais valores, e só tentar extrair um caráter de dentro delas depois de ter certeza de que o valor retornado não é EOF.


Estou avisado (2).

PS2: Eu acho muito pouco provável que não haja explicações bem melhores do que a minha na Internet. Se você procurou no Google e não encontrou resposta, seus termos de pesquisa não devem ter sido muito bons.


Acredite, eu tentei.

Mais uma vez obrigado. Foi esclarecedor.

Abraço!



5. Re: EOF e quebra de linha Windows && Linux

Perfil removido
removido

(usa Nenhuma)

Enviado em 15/09/2014 - 21:06h

Alem do problema do fim de linha (CR+LF) existe tambem o problema da ANSI/WINDOWS 1252 contra o UTF-8.

Assim, antes de levar o arquivo do Windows para ser lido no linux precisa ajustar as duas coisas.

O Bloco de notas salva em UTF-8, mas nao permite mudar o fim e linha...

Entao instale uma versao do GEDIT para Windows ele permite fazer as duas coisas

Quando chegar no Linux confira como comando file -i se esta em UTF-8

qualquer duvida pode fazer conversao no Linux usando ICONV.

boa sorte


6. Re: EOF e quebra de linha Windows && Linux

Paulo
paulo1205

(usa Ubuntu)

Enviado em 15/09/2014 - 23:14h

Consegui contornar o problema causado inadvertidamente pelo foxbit3r, ao esquecer de usar a tag [/code] para fechar os blocos com amostra de código que ele abriu com “[code]” (na verdade, foi um pouco pior, porque ele repetiu a tag de abertura na hora de fechar), e o fiz editando a minha postagem e colocando os “[/code]” que faltaram na mensagem dele. Mesmo assim, seria melhor se ele consertasse a mensagem dele.

Por falar em consertar, há outro problema no que ele escreveu, pois ele disse que a terminação de linhas no Windows é "\n\r", quando o correto é "\r\n" (que, aliás, é também a convenção para fim de linha usada em diversos protocolos da Internet, incluindo o HTTP).


7. Re: EOF e quebra de linha Windows && Linux

Paulo
paulo1205

(usa Ubuntu)

Enviado em 15/09/2014 - 23:30h

NewWave escreveu:

Errado. Ele vai achar o LF que vem logo depois do CR, e vai começar a linha nova exatamente no mesmo ponto em que o Windows começaria. A diferença é que pode haver um CR sobrando no final de cada linha. Esse CR geralmente é categorizado como caráter de espaçamento (ver função isblank()), e não provoca efeito visível se você simplesmente reproduzir o conteúdo do arquivo num terminal de texto ou impressora (se tudo estver configurado corretamente, claro).


Estou avisado. Resta saber como eu vou lidar com isso na prática.


Sugestão: se o último caráter da linha lida for um '\r', apague-o, quer sobrescrevendo esse byte com um byte nulo ('\0'), se for uma string do C, quer, se você estiver usando std::string ou outra classe do C++, explicitamente removendo o último caráter (std::string::resize(), std::string::erase(), std::string::pop_back() ou outro meio que você preferir).






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts