C++ dúvida a respeito do seguinte comando: while (cin>>...) [RESOLVIDO]

1. C++ dúvida a respeito do seguinte comando: while (cin>>...) [RESOLVIDO]

Jardel Nunes
JardelNunes

(usa Ubuntu)

Enviado em 14/01/2016 - 17:55h

Olá pessoal. Estou iniciando em C++ pelo livro "princípios e práticas de programação com C++". Me deparei com o seguinte código durante a minha leitura:

#include <iostream>

#include <string>
#include <vector>
#include <algorithm>
#include <cmath>
#include <locale.h>

using namespace std;
inline void keep_window_open() {char ch; cin>>ch;}

int main (){


setlocale(LC_ALL, "Portuguese");

string anterior= " ";
string atual;
while (cin>>atual){
if(anterior == atual)
cout << "palavra repetida: " << atual << '\n';

anterior = atual;
}


}

Ao eu escrever uma frase como "O gato gato pulou pulou muito" o programa emite como saída, depois de eu clicar 'enter', o seguinte:

palavra repetida: gato
palavra repetida: pulou

Não estou entendendo por que ocorre dessa maneira: primeiro escrevo a frase completa, depois clico enter, e depois mostra quais são as palavras repetidas. Onde é armazenado o conjunto das palavras repetidas? E ''while (cin>>atual)'', o que isso significa? Porque não ocorre dessa maneira: ao repetir uma palavra, já mostra qual a palavra repetida logo após? Porque e como isso ocorre apenas no final (após eu clicar 'enter')? Porque o comando if e os seus resultados é executado só no final, depois do anterior = atual, sendo que o if está antes do anterior = atual?

OBS: estou usando o Dev-C++ 5.11

Desde já agradeço ;D!



  


2. Re: C++ dúvida a respeito do seguinte comando: while (cin>>...) [RESOLVIDO]

Paulo
paulo1205

(usa Ubuntu)

Enviado em 16/01/2016 - 04:42h

Porque tanto o ambiente de execução quanto o sistema operacional trabalham com buffers.

Buffers são regiões de memória usadas para guardar temporariamente dados recebidos de uma das pontas do canal de comunicação antes de entregá-los à outra ponta. Geralmente o emprego de buffers ajuda a diminuir a quantidade total de operações ao longo do canal como um todo, e isso é especialmente valioso quando uma das pontas tem velocidade muito diferente da da outra ponta.

No seu caso, provavelmente está acontecendo o seguinte:

    1) A primeira operação de leitura do seu programa tenta consumir dados do buffer de leitura associado a std::cin, mas o encontra vazio.

    2) De modo a poder satisfazer a solicitação de leitura solicitada pelo programa, o ambiente de execução é obrigado a pedir dados ao sistema operacional, e ele o faz pedindo uma quantidade de bytes suficiente para encher todo o buffer logo de uma vez (tipicamente 1024, 4096 ou 8192 bytes, mas isso pode ser alterado).

    3) O sistema operacional tenta obter os dados solicitados a partir da fonte de dados. Poderia ser um arquivo, um fluxo de comunicação via rede, uma porta serial ou outra fonte de dados qualquer, e cada uma potencialmente teria um tipo de tratamento distinto das demais, mas provavelmente todos eles com um ou mais tipos de buffers e cache. No seu caso, você está lendo de um terminal (físico, como o console, ou virtual, como uma janela de terminal dentro do ambiente gráfico ou via conexão de rede).

    4) Tipicamente o sistema operacional trata o terminal como um dispositivo orientado a linha (isso pode ser mudado, mas o seu programa não faz qualquer mudança nesse sentido). Isso significa que o sistema só vai entregar os dados obtidos quando encontrar uma marca de fim de linha, mesmo que a marca de fim de linha só ocorra após a quantidade de caracteres solicitada pelo ambiente de execução. Até que apareça a marca de fim de linha, os caracteres obtidos são colocados no buffer do device driver que trata o terminal (a não ser que ocorra alguma situação que interrompa o fluxo de dados, tal como fim de comunicação ou erro; nesse caso o sistema entrega os dados imediatamente).

    5) Quando o sistema operacional entrega os dados ao ambiente de execução, tais dados não são diretamente repassados ao cliente, mas são postos no buffer do ambiente de execução.

    6) Nesse momento é que o ambiente de operação vai tomar as providências para entregar ao programa os dados solicitados. No seu caso, essa entrega se dá através da transferência de caracteres presentes no buffer para o interior da sua string, de acordo com os critérios de std::operator>>(istream &, string &), que é pular espaços em branco no início do buffer e transferir todos os caracteres não-espaço até a ocorrência do próximo espaço em branco, sendo que:

        6.a) se os caracteres do buffer acabarem antes do próximo espaço em branco e o sistema operacional não tiver indicado fim do fluxo de dados, o ambiente de execução vai solicitar mais dados ao sistema operacional; e

        6.b) não necessariamente a nova solicitação ao sistema operacional vai provocar a leitura de mais dados do teclado, pois pode haver dados no buffer do device driver, remanescentes da leitura anterior que tenha consumido menos caracteres do que a quantidade digitada até a marca de fim de linha.

    7) O resultado da operação de leitura é refletido em std::cin, e o valor de std::cin é convertido para booleano e testado como condição do comando de repetição while no seu programa. Se for verdadeiro, uma nova iteração do loop prossegue a partir do passo (6); caso contrário, o loop termina.


3. RE: C++ DÚVIDA A RESPEITO DO SEGUINTE COMANDO: WHILE (CIN>>...)

Jardel Nunes
JardelNunes

(usa Ubuntu)

Enviado em 20/01/2016 - 19:31h

Resposta sensacional. Agora sim entendi. Muito obrigado!!






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts