paulo1205
(usa Ubuntu)
Enviado em 06/11/2020 - 21:22h
Tanto faz.
O
fscanf não lê (ou não precisa ler) linhas inteiras de uma vez. Mesmo quando você trabalha com arquivos de texto (ou com o console de texto), as funções de entrada e saída consideram que estão trabalhando com um fluxo de
bytes . No caso específico de
scanf ()/fscanf[/i]() e outras da mesma família, o que vai ser extraído do fluxo de entrada serão apenas os caracteres (ou
bytes ) que forem relevantes para atender à
string de formatação que você especificar; a leitura para assim que aparecer algum caráter/
byte que não atenda ao critério especificado.
Não sei quão iniciante você é, mas mesmo que seja bem novato, acho interessante ler atentamente uma boa documentação da família de
scanf () (um documento realmente muito bom a respeito dela é a documentação
on-line que acompanha o Linux; na Internet, você pode procurar por “
linux manpage scanf ”). É importante fazer isso para entender as regras de formação da
string de formatação, saber como funciona o descarte automático de espaços em branco (que inclui eventuais quebras de linha) e quando ele não ocorre, que tipos de leituras podem ser usadas com quais tipos diferentes de de variáveis, como identificar se houve erro total ou parcial durante a operação de leitura etc.
Leia realmente a documentação. Se tiver dúvidas, traga-as aqui.
No caso do seu programa, parece que o primeiro número indica quantas linhas com pares de números estarão nas linhas seguintes. Se realmente for esse o caso, o exemplo abaixo, ilustra como fazer, com comentários explicativos e apresentando alternativas para ler os pares de valores das linhas em que eles ocorrem em par.
int n_linhas;
// Sempre teste o valor de retorno de scanf()/fscanf()/sscanf() para ver se a leitura foi bem sucedida.
// O valor de retorno indica quantas conversões foram realizadas com sucesso. Como a string de
// formatação abaixo só especifica uma conversão, então uma leitura bem-sucedida tem de retornar
// o valor 1.
// Note que a conversão "%d" produz descarte automático de espaços em branco (incluindo quebras
// de linha) que ocorram antes de começarem a aparecer os dígitos que compõem o número inteiro.
// Depois que os dígitos começarem a aparecer, o primeiro caráter que não for um dígito encerra a
// leitura, e tal caráter ficará no fluxo de leitura para ser consumido pela próxima operação de leitura.
if(fscanf(file_pointer, "%d", &n_linhas)==1 && n_linhas>0){
for(int n=0; n<n_linhas; ++n){
double x, y;
// A leitura seguinte tenta ler dois valores numa única chamada de fscanf(), pois há duas conversões
// especificadas na string de formatação, o que implica que uma leitura bem-sucedida deve retornar
// o valor 2.
// As duas conversões indicam argumentos do tipo double (ponto-flutuante de dupla precisão). Essa
// conversão também provoca o descarte automático de espaços em branco que antecedem os carac-
// teres que formam o valor numérico, o que é desejável, uma vez que a quebra de linha da leitura
// anterior ainda estará presente no fluxo de entrada, pois foi deixada lá pela operação de leitura
// que ocorreu anteriormente.
if(fscanf(file_pointer, "%lf %lf", &x, &y)==2){
/*
Outras possíveis formas de fazer e que produzem o mesmo efeito acima:
• “if(fscanf(file_pointer, "%lf%lf", &x, &y)==2)”: é possível suprimir o espaço entre as conversões na
string de formatação porque cada uma delas tem seu próprio descarte de espaços em branco no
momento de execução. Como o arquivo de entrada usa espaços para separar um valor do outro,
você pode contar com o descarte da segunda conversão, assim como já contava implicitamente
com o descarte da primeira para passar para a linha seguinte à da leitura anterior.
• “if(fscanf(file_pointer, "%lf", &x)==1 && fscanf(file_pointer, "%lf", &y)==1)”: é perfeitamente seguro
partir a operação de leitura em duas, desde que você cuide adequadamente do valor de retorno
de cada uma dessas operações. Partir em duas deixa bem claro como scanf () não se preocupa
com linhas, mas sim apenas com aquilo que você especificar que deve ser consumido do fluxo de
caracteres.
*/
// ... Usa os valores lidos de x e y...
}
else{
// Operação de leitura falhou (valor retornado por fscanf() diferente do esperado). Dê o tratamento
// que for adequado para o seu programa (abortar a execução, tentar novamente, ignorar, ou o que
// você preferir).
}
}
}
... Então Jesus afirmou de novo: “(...) eu vim para que tenham vida, e a tenham plenamente.” (João 10:7-10)