Ir ao conteúdo

Posts recomendados

Postado

Jeesuus!

Jeeesuuus!

 

Nâo era nada disso não, cada vez que você usa fgets você lê uma linha do arquivo, a linha permanece no arquivo, mas o pointer pula para a próxima linha então na próxima leitura será lida a próxima linha se houver, era só colocar o código que postei dentro do while do programa que você postou e fazer as modificações que eu disse. Assim, o próprio programa ia se encarrerar de carregar cada linha e gerar outra linha já no formato csv e gravar no outro arquivo.

 

Então copie o que estiver entre o main e o return no programa que postei e coloque dentro do seu while do seu post # 46

 

depois é só mudar isso:

char frase[2000];
while (fgets(frase, 2000, arquivo) != NULL){

Para isso:

char linha[100];
fgets(linha, 100, arquivo);
while (fgets(linha, 100, arquivo) != NULL){

E apagar essas linhas:

char linha[100] = "002   41615446   Jordan Belchiorinho Lagos                         02/09/1996           F";

E

printf("%s", frase);

Coloque o arquivo txt na mesma pasta que o programa e execute, o aquivo csv deverá aparecer na tela.

 

arqcsv.GIF

Postado
4 horas atrás, Weverson Meireles disse:

alvez  seja isso, na minha cabeça, pege o arquivo inteiro seria mais simples mas não tenho conhecimento para isso. 

E pelo que me demonstraram é mais fácil fazer um por um. 

Estou montando para ler linha por linha, assim que terminar, envio o resultado a vocês

 

Não faz sentido o que está pensando em fazer.

 

 

Entenda que SEMPRE vai ser linha a linha. csv é um formato orientado a linha. Um arquivo CSV é uma tabela. No seu caso uma tabela de N linhas por 5 colunas. Cada linha tem um registro. Cada registro tem um certo número de campos separados por um delimitador.

 

Não entendo porque está indo por caminhos tão complicados. Eu já tentei um certo número de vezes aqui acima te mostrar o que tem que fazer, e depois até te mostrei um programa que faz de fato isso com o resultado logo abaixo. O seu programa original já lê as linhas corretamente. Apenas pegue a tal frase que é char[2000] e passe pelo código de eu te mostrei. É só isso.

 

Esse é o loop do seu programa original

 

    FILE* arquivo;
    arquivo = fopen("ARQ01.txt", "r");
    if (arquivo == NULL)
    {
        printf("não foi possível abrir o arquivo\n");
        getchar();
        exit(0);
    }

    char frase[2000];
    while (fgets(frase, 2000, arquivo) != NULL) { printf("%s", frase); }

    fclose(arquivo);

 

Que mostra

 

001 14/05/2021 Exportacao F
002 12012435 Nilo Pontes Sousa 17/02/2000 F
002 21910420 Miguel Veiga Carrilho 26/11/1997 F
002 31813713 Teresinha Fragoso Fontinha 14/01/1997 F
002 41615446 Jordan Belchiorinho Lagos 02/09/1996 F
002 52011977 Iara Quinteiro Melancia 14/02/1996 F
002 62010992 Neusa Gomide Canario 02/04/2002 F
002 71711935 Abdul Modesto Pureza 27/01/1992 F
002 82020657 Ludmila Frade Capistrano 09/05/1995 F
002 91704871 Kyami Furtado Mafra 19/05/1978 F
002 101615740 Carmen Guedelha Sacadura 16/03/1997 F
002 111911901 Jonas Rosa Regodeiro 18/05/1992 F
002 122011094 Lucia Redondo Lisboa 06/09/1997 F
002 131714919 Josefina Loio Banha 09/12/1996 F
002 141512419 Paloma Tabosa Quintal 29/09/1998 F
002 152112795 Flavia Ornelas Ribeiro 07/03/2001 F
002 162011978 Salomao Conde Ramos 11/01/2000 F
002 172012217 Mirian Vinhas Souto 06/02/1999 F
002 182012184 Axel Moita Camacho 10/10/1991 F
002 192020139 Lyana Pedro Noronha 22/11/2000 F
002 202012047 Ronaldo Braga Netto 22/07/2000 F

 

Para o arquivo que você mesmo postou.

 

Esse é o loop que lê o arquivo todo:

 

    char frase[2000];
    while (fgets(frase, 2000, arquivo) != NULL) { printf("%s", frase); }

 

Não foi você que escreveu esse programa?

Você tem noção do que esse loop faz?

Consegue ver aí de onde sai o resultado que você vê na tela?

 

É a saída do programa que você postou e só precisa colocar 4 vírgulas em cada registro.

 

Só que eu te mostrei um exemplo simples que tem até NUMERADOS os pontos onde deve colocar os delimitadores...

[1] [2] [3] e [4].

 

Então tudo sugere que se você enfiar o código que eu te mostrei lá naquele ponto do loop do programa que você escreveu tudo vai funcionar. 

 

Como saber?  É só olhar. Mas também pode, como eu te mostrei, importar o arquivo para uma planilha e ver.

 

Esse formato tem mais de 40 anos

 

 

Um OUTRO exemplo

 

#include <stdio.h>
#include <string.h>

int main(void)
{
    const char dlm     = ';';                      // o delimitador
    FILE*      arquivo = fopen("ARQ01.txt", "r");  // o arquivo
    if (arquivo == NULL) return -1;

    char  frase[2000];
    char* p = fgets(frase, 2000, arquivo);

    while (p != NULL)
    {
        // procura o primeiro branco
        while (*p != 0)
        {
            if (*p != ' ')
                p = p + 1;  // avanca: não e branco
            else
            {
                *p = dlm;    // troca pelo delimitador   [1]
                p  = p + 1;  // avanca
                break;
            }
        };
        // se saiu sem achar o branco o arquivo
        // // tem problemas: cancela
        if (*p == 0)
        {
            fclose(arquivo);
            return -2;
        };

        // procura o segundo branco
        while (*p != 0)
        {
            if (*p == ' ')
            {
                *p = dlm;  // troca                      [2]
                p  = p + 1;
                break;  // sai do loop
            }
            p = p + 1;  // avanca
        };
        // se saiu sem achar o branco o arquivo
        // // tem problemas: cancela
        if (*p == 0)
        {
            fclose(arquivo);
            return -3;
        };

        // agora tem o lance do nome que pode ter varios
        // brancos entao o fácil: seguir pela direita
        int fim = strlen(frase) - 1;  // aponta pra letra final
        // esta claro que o ultimo campo e uma letrinha
        // entao o delimitador vem antes, e
        // aponta p para o lugar certo:
        p  = frase + fim - 2;
        *p = dlm;    // o quarto campo. falta 1          [3]
        p  = p - 1;  // agora esta no fim da data

        // agora o nome
        while (p != frase)
        {  // procura para tras ate o inicio
            if (*p == ' ')
            {
                *p = dlm;  // troca                      [4]
                break;     // sai do loop
            }
            p = p - 1;  // volta uma letra
        }
        // se chegou ate o comeco entao não achou nenhum branco
        // e o arquivo esta zoado: cancela
        if (p == frase)
        {
            fclose(arquivo);
            return -4;
        };

        // tudo certo! Entao mostra essa linha
        printf("%s", frase);
        p = fgets(frase, 2000, arquivo);  // le a proxima

    };  // while()
    fclose(arquivo);
    return 0;
}

 

 

Pois é: o seu programa com aquele pedaço que eu te mostrei inserido no loop que eu te mostrei. O loop que você escreveu.

 

Esse programa mostra

 

002;12012435;Nilo Pontes Sousa;17/02/2000;F
002;21910420;Miguel Veiga Carrilho;26/11/1997;F
002;31813713;Teresinha Fragoso Fontinha;14/01/1997;F
002;41615446;Jordan Belchiorinho Lagos;02/09/1996;F
002;52011977;Iara Quinteiro Melancia;14/02/1996;F
002;62010992;Neusa Gomide Canario;02/04/2002;F
002;71711935;Abdul Modesto Pureza;27/01/1992;F
002;82020657;Ludmila Frade Capistrano;09/05/1995;F
002;91704871;Kyami Furtado Mafra;19/05/1978;F
002;101615740;Carmen Guedelha Sacadura;16/03/1997;F
002;111911901;Jonas Rosa Regodeiro;18/05/1992;F
002;122011094;Lucia Redondo Lisboa;06/09/1997;F
002;131714919;Josefina Loio Banha;09/12/1996;F
002;141512419;Paloma Tabosa Quintal;29/09/1998;F
002;152112795;Flavia Ornelas Ribeiro;07/03/2001;F
002;162011978;Salomao Conde Ramos;11/01/2000;F
002;172012217;Mirian Vinhas Souto;06/02/1999;F
002;182012184;Axel Moita Camacho;10/10/1991;F
002;192020139;Lyana Pedro Noronha;22/11/2000;F
002;202012047;Ronaldo Braga Netto;22/07/200; F

 

E se o seu programa fosse tst.exe:

 

PS C:\ ./tst
002;12012435;Nilo Pontes Sousa;17/02/2000;F
002;21910420;Miguel Veiga Carrilho;26/11/1997;F
002;31813713;Teresinha Fragoso Fontinha;14/01/1997;F
002;41615446;Jordan Belchiorinho Lagos;02/09/1996;F
002;52011977;Iara Quinteiro Melancia;14/02/1996;F
002;62010992;Neusa Gomide Canario;02/04/2002;F
002;71711935;Abdul Modesto Pureza;27/01/1992;F
002;82020657;Ludmila Frade Capistrano;09/05/1995;F
002;91704871;Kyami Furtado Mafra;19/05/1978;F
002;101615740;Carmen Guedelha Sacadura;16/03/1997;F
002;111911901;Jonas Rosa Regodeiro;18/05/1992;F
002;122011094;Lucia Redondo Lisboa;06/09/1997;F
002;131714919;Josefina Loio Banha;09/12/1996;F
002;141512419;Paloma Tabosa Quintal;29/09/1998;F
002;152112795;Flavia Ornelas Ribeiro;07/03/2001;F
002;162011978;Salomao Conde Ramos;11/01/2000;F
002;172012217;Mirian Vinhas Souto;06/02/1999;F
002;182012184;Axel Moita Camacho;10/10/1991;F
002;192020139;Lyana Pedro Noronha;22/11/2000;F
002;202012047;Ronaldo Braga Netto;22/07/200; F

 

E se jogar isso em um arquivo teste.txt

 

PS C:\ .\tst > teste.txt

 

Então vai claro criar esse arquivo com aquelas linhas, o tal csv

 

E se usar o Planilhas do Google e tentar importar isso?

 

a-i1.jpg.895a07bcf4f2e35cce7a4328f631f5c2.jpg

 

 

 

So que o delimitador padrão é a vírgula, como te disse um certo número de vezes. E parece que você quer usar ; Então

 

a-i2.jpg.eb033f24dae0d81969b2a2fddc811b1c.jpga-i2.jpg.eb033f24dae0d81969b2a2fddc811b1c.jpg

 

 

 

E aí vem a planilha importada a partir do arquivo que seu programa gerou:

 

a-i3.jpg.d330c9026120639605540fe7d74d4d5b.jpg

 

Que é o esperado

 

 

RODE isso e procure entender. Se não entender pergunte algo objetivo pra  gente ver outra maneira de te explicar...

 

 

Postado
5 horas atrás, JorgeGus disse:

Além disso:

Coloque um fgets fora do while para descartar a linha do cabeçalho;

Crie outro arquivo para receber os registros em formato CSV;

E use fprintf no lugar de printf para gravar os registros, nesse caso o primeiro parâmetro é o nome do arquivo de destino.

Faltam no caso essas partes aqui para editar.

Postado

Entenda que a planilha separa os dados em 5 colunas, de A a E. Isso é o resultado de riar um arquivo csv.

 

Essas são as 3 primeiras linhas de seu arquivo

001 14/05/2021 Exportacao F
002 12012435 Nilo Pontes Sousa 17/02/2000 F
002 21910420 Miguel Veiga Carrilho 26/11/1997 F

 

Acho que já deu pra ver que tem só 4 campos na primeira linha. Então está errado. Um arquivo CSV é uma tabela MxN. Todas as linhas tem que ter 4 delimitadores para definir 5 campos mesmo que vazios. E eu te passei um link com a definição, dias atrás, se isso for importante. Mas faça o simples: corrija ou apague essa linha ou mude  o seu programa para ignorar linhas com erro.

Postado
4 minutos atrás, arfneto disse:

apague essa linha ou mude  o seu programa para ignorar linhas com erro.

Eu apaguei esta linha. 

Chegou a ver o programa que criei anteriormente? Ficou extenso mas acho que consigo apresentar o que quero.

Postado
6 minutos atrás, Weverson Meireles disse:

Coloque um fgets fora do while para descartar a linha do cabeçalho;

 

Não é um cabeçalho. Está só errado. O campo de cabeçalho teria os nomes dos campos e teria claro que ter cinco valores.

Algo assim usando os  nomes que o autor usou no programa:
 

fixo matricula nome data fixof

 

E veria algo como 
 

image.png.dd8ccb1d816a4054dcab481bbe592ed0.png

 

 

Seria preciso mudar a lógica do programa que eu mostrei na hora de ler esse campo, fosse ele de fato um header

2 minutos atrás, Weverson Meireles disse:

Chegou a ver o programa que criei anteriormente? Ficou extenso mas acho que consigo apresentar o que quero

 

17 minutos atrás, arfneto disse:

 

Não faz sentido o que está pensando em fazer.

 

 

 

Como eu disse na primeira linha, está errado. Deve ler os dados do arquivo. Não pode fazer um programa com constantes. Isso era, como te expliquei umas vezes, para chegar rápido a algo que funcionasse para uma linha. 

 

E depois colocar naquele loop....

 

 

 

 

 

6 horas atrás, JorgeGus disse:

E use fprintf no lugar de printf para gravar os registros, nesse caso o primeiro parâmetro é o nome do arquivo de destino

 

Não é. O primeiro parâmetro é um ponteiro para FILE. O nome do arquivo é usado no fopen() apenas.

Postado
30 minutos atrás, arfneto disse:
#include <stdio.h>
#include <string.h>

int main(void)
{
    const char dlm     = ';';                      // o delimitador
    FILE*      arquivo = fopen("ARQ01.txt", "r");  // o arquivo
    if (arquivo == NULL) return -1;

    char  frase[2000];
    char* p = fgets(frase, 2000, arquivo);

    while (p != NULL)
    {
        // procura o primeiro branco
        while (*p != 0)
        {
            if (*p != ' ')
                p = p + 1;  // avanca: não e branco
            else
            {
                *p = dlm;    // troca pelo delimitador   [1]
                p  = p + 1;  // avanca
                break;
            }
        };
        // se saiu sem achar o branco o arquivo
        // // tem problemas: cancela
        if (*p == 0)
        {
            fclose(arquivo);
            return -2;
        };

        // procura o segundo branco
        while (*p != 0)
        {
            if (*p == ' ')
            {
                *p = dlm;  // troca                      [2]
                p  = p + 1;
                break;  // sai do loop
            }
            p = p + 1;  // avanca
        };
        // se saiu sem achar o branco o arquivo
        // // tem problemas: cancela
        if (*p == 0)
        {
            fclose(arquivo);
            return -3;
        };

        // agora tem o lance do nome que pode ter varios
        // brancos entao o fácil: seguir pela direita
        int fim = strlen(frase) - 1;  // aponta pra letra final
        // esta claro que o ultimo campo e uma letrinha
        // entao o delimitador vem antes, e
        // aponta p para o lugar certo:
        p  = frase + fim - 2;
        *p = dlm;    // o quarto campo. falta 1          [3]
        p  = p - 1;  // agora esta no fim da data

        // agora o nome
        while (p != frase)
        {  // procura para tras ate o inicio
            if (*p == ' ')
            {
                *p = dlm;  // troca                      [4]
                break;     // sai do loop
            }
            p = p - 1;  // volta uma letra
        }
        // se chegou ate o comeco entao não achou nenhum branco
        // e o arquivo esta zoado: cancela
        if (p == frase)
        {
            fclose(arquivo);
            return -4;
        };

        // tudo certo! Entao mostra essa linha
        printf("%s", frase);
        p = fgets(frase, 2000, arquivo);  // le a proxima

    };  // while()
    fclose(arquivo);
    return 0;
}

Pois é, eu tentei inserir no seu, mas quando rodo o programa, as virgulas não aparecem corretamente como na foto do resultado que me mandou 

E eu tirei o ";"

 

Até utilizando esse seu codigo

Postado
47 minutos atrás, arfneto disse:

Não é. O primeiro parâmetro é um ponteiro para FILE. O nome do arquivo é usado no fopen() apenas.

 

Ops! Tem razão, a explicação saiu errada, mas código está certo.

FILE *arqcsv = fopen("ARQ01.csv", "w");

fprintf(arqcsv, "002,%s,%s,%s,F\n", matr, nome, dtn);

 

  • Curtir 1
Postado

Está difícil entender o que você está modificando, era basicamente uma questão de copiar e colar uma das soluções propostas dentro do programa que você mesmo postou e direcionar para um arquivo.

Postado
1 minuto atrás, JorgeGus disse:

Está difícil entender o que você está modificando

Posicionamento de virgula. Mas já finalizei com o programa que o colega me passou. Não conseguiria sem a ajuda de vocês  

Postado
1 minuto atrás, Weverson Meireles disse:

Posicionamento de virgula. Mas já finalizei com o programa que o colega me passou. Não conseguiria sem a ajuda de vocês  

 

Ok, então dê uma olhada na solução que eu tinha proposto já finalizada e tente entender.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
    FILE *arqtxt = fopen("ARQ01.txt", "r");
    FILE *arqcsv = fopen("ARQ01.csv", "w");
    char linha[100];
    fgets(linha, 100, arqtxt);
    while (fgets(linha, 100, arqtxt) != NULL){
        char reg[4];
        char matr[11];
        char nome[51];
        char dtn[11];
        sscanf (linha,"%s%s", reg, matr);
        strncpy(nome, linha + 17, 50);
        nome[50] = 0;
        for (int c = 49; c >= 0; c--) {
            if (nome[c] == ' ')
                nome[c] = 0;
            else
                break;
        }
        strncpy(dtn, linha + 67, 10);
        dtn[10] = 0;
        fprintf(arqcsv, "002,%s,%s,%s,F\n", matr, nome, dtn);
    }
    fclose(arqtxt);
    fclose(arqcsv);
    return 0;
}

 

Postado
2 minutos atrás, Weverson Meireles disse:

Agora estou com outro problema. Realizar a leitura de um arquivo e ordena-lo com Quicksort: 

 

Questao 3.png

É só procurar aqui no fórum, você deve encontrar várias soluções.

Postado
1 minuto atrás, JorgeGus disse:

Ok, então dê uma olhada na solução que eu tinha proposto já finalizada e tente entender.

Eu fiz ela também Mostrei, linha por linha e gravei com fprintf. Graças a paciência de vocês consegui compreender  kk 

agora, JorgeGus disse:

É só procurar aqui no fórum, você deve encontrar várias soluções.

Estou procurando, este clube tem muitas informações importantes, esta me ajudando demais. Só queria mostrar o que eu tinha feito: 

 

 

#include <stdio.h>

int tamVetor = 10;
int vetor[] = {0,1,2,3,4,5,6,7,8,9};

void insertionSort() {

    for (int i = 1; i < tamVetor; i++) {
		int item = vetor[i];
		int j = i - 1;
		
		while ((j >= 0) && (vetor[j] > item)) {
			vetor[j + 1] = vetor[j];
			j--;
		}
		
		vetor[j + 1] = item;
	}
}
void selectionSort() { 
	int aux, min;
	for (int i = 0; i < (tamVetor-1); i++) {
		min = i;
		for (int j = (i+1); j < tamVetor; j++) {
			if(vetor[j] < vetor[min]) 
				min = j;
		}
		if (i != min) {
			aux = vetor[i];
			vetor[i] = vetor[min];
			vetor[min] = aux;
		}
	}
}
void bubbleSort(int posicao){ 
    if (posicao < 1)return; 
 
    for (int i=0; i< posicao; i++) {
        if (vetor[i] > vetor[i+1]) {
        	int temp = vetor[i];
		    vetor[i] = vetor[i+1];
		    vetor[i+1] = temp; 
		}
	}
    bubbleSort(posicao-1); 
}
void quickSort(int inicio, int final) {
	int i, j, pivo, aux;
	i = inicio;
	j = final-1;
	pivo = vetor[(inicio + final) / 2];
	while(i <= j) {
		while(vetor[i] < pivo && i < final) {
			i++;
		}
		while(vetor[j] > pivo && j > inicio) {
			j--;
		}
		if(i <= j) {
			aux = vetor[i];
			vetor[i] = vetor[j];
			vetor[j] = aux;
			i++;
			j--;
		}
	}
	if(j > inicio)
		quickSort(inicio, j+1);
	if(i < final)
		quickSort(i, final);
}
void heapSort(int n) {
   int i = n / 2, pai, filho, t;
   while(true) {
      if (i > 0) {
          i--;
          t = vetor[i];
      } else {
          n--;
          if (n <= 0) return;
          t = vetor[n];
          vetor[n] = vetor[0];
      }
      pai = i;
      filho = i * 2 + 1;
      while (filho < n) {
          if ((filho + 1 < n)  &&  (vetor[filho + 1] > vetor[filho]))
              filho++;
          if (vetor[filho] > t) {
             vetor[pai] = vetor[filho];
             pai = filho;
             filho = pai * 2 + 1;
          } else {
             break;
          }
      }
      vetor[pai] = t;
   }
}

int buscaSequencial(int elemento) {
	for (int i = 0; i < tamVetor; i++) {
		if (vetor[i] == elemento)
			return i;
	}
	return -1;
}
int buscaBinaria(int elemento, int limEsq, int limDir) {
	int meio = (limEsq + limDir)/2;
	if (vetor[meio] == elemento)
		return meio;
	
	if (limEsq >= limDir)
		return -1; // não encontrado
	
	else if (vetor[meio] < elemento)
		return buscaBinaria(elemento, meio+1, limDir);
	else
		return buscaBinaria(elemento, limEsq, meio-1);
}



int main(void) {

	for(int i=0; i< tamVetor; i++) {
		printf("%i\n", vetor[i]);
	}

	puts("Pos ordenacao\n\n");
    //insertionSort();
    //selectionSort();
    //bubbleSort(tamVetor-1);
    //quickSort(0, 9);
    heapSort(10);
	for(int i=0; i< tamVetor; i++) {
		printf("%i\n", vetor[i]);
	}
	
}

 

Agora estou tentando ordenar 10 mil números aleatórios que estão dentro de um arquivo.

 

Postado
1 hora atrás, Weverson Meireles disse:

Pois é, eu tentei inserir no seu, mas quando rodo o programa, as virgulas não aparecem corretamente como na foto do resultado que me mandou 

E eu tirei o ";"

 

Até utilizando esse seu codigo

O programa que eu te mostrei vai gerar o resultado que eu te mostrei.

 

Que significa "eu tirei o ;"??

 

Porque não posta o código  que usou????

1 hora atrás, Weverson Meireles disse:

Pois é, eu tentei inserir no seu, mas quando rodo o programa, as virgulas não aparecem corretamente como na foto do resultado que me mandou 

E eu tirei o ";"

 

Até utilizando esse seu codigo

O programa que eu te mostrei vai gerar o resultado que eu te mostrei.

 

Que significa "eu tirei o ;"??

 

Porque não posta o código  que usou????

Postado
7 minutos atrás, JorgeGus disse:

Agora estou com outro problema. Realizar a leitura de um arquivo e ordena-lo com Quicksort: 

 

Poste um tópico. E um código. 

 

Se espera que o código aqui possa ajudar outros com problemas semelhantes. Se você misturar as coisas ninguém vai conseguir achar.

 

Então pergunte algo objetivo, como "o quicksort em C esta me dando esse problema para esse código. E poste os dois ;) o problema e o código se tiver um

 

1 minuto atrás, Weverson Meireles disse:

Exatamente o seu, só usei a virgula 

poste o código que usou.

 

O programa que te mostrei vai dar o resultado que te mostrei. 

Postado
2 minutos atrás, arfneto disse:

Poste um tópico. E um código. 

 

Se espera que o código aqui possa ajudar outros com problemas semelhantes. Se você misturar as coisas ninguém vai conseguir achar.

Perfeito, realmente espero que possa ajudar a outros como me ajudou 

Esse foi o código que utilizei mostrando o resultado como esperado:

 

#include <stdio.h>
#include <string.h>

int main(void)
{
    const char dlm     = ',';                      // o delimitador
    FILE*      arquivo = fopen("ARQ01.txt", "r");  // o arquivo
    if (arquivo == NULL) return -1;

    char  frase[2000];
    char* p = fgets(frase, 2000, arquivo);

    while (p != NULL)
    {
        // procura o primeiro branco
        while (*p != 0)
        {
            if (*p != ' ')
                p = p + 1;  // avanca: não e branco
            else
            {
                *p = dlm;    // troca pelo delimitador   [1]
                p  = p + 1;  // avanca
                break;
            }
        };
        // se saiu sem achar o branco o arquivo
        // // tem problemas: cancela
        if (*p == 0)
        {
            fclose(arquivo);
            return -2;
        };

        // procura o segundo branco
        while (*p != 0)
        {
            if (*p == ' ')
            {
                *p = dlm;  // troca                      [2]
                p  = p + 1;
                break;  // sai do loop
            }
            p = p + 1;  // avanca
        };
        // se saiu sem achar o branco o arquivo
        // // tem problemas: cancela
        if (*p == 0)
        {
            fclose(arquivo);
            return -3;
        };

        // agora tem o lance do nome que pode ter varios
        // brancos entao o fácil: seguir pela direita
        int fim = strlen(frase) - 1;  // aponta pra letra final
        // esta claro que o ultimo campo e uma letrinha
        // entao o delimitador vem antes, e
        // aponta p para o lugar certo:
        p  = frase + fim - 2;
        *p = dlm;    // o quarto campo. falta 1          [3]
        p  = p - 1;  // agora esta no fim da data

        // agora o nome
        while (p != frase)
        {  // procura para tras ate o inicio
            if (*p == ' ')
            {
                *p = dlm;  // troca                      [4]
                break;     // sai do loop
            }
            p = p - 1;  // volta uma letra
        }
        // se chegou ate o comeco entao não achou nenhum branco
        // e o arquivo esta zoado: cancela
        if (p == frase)
        {
            fclose(arquivo);
            return -4;
        };

        // tudo certo! Entao mostra essa linha
        printf("%s", frase);
        p = fgets(frase, 2000, arquivo);  // le a proxima

    };  // while()
    fclose(arquivo);
    return 0;
}

 

  • Curtir 1
Postado
21 minutos atrás, JorgeGus disse:

Ok, então dê uma olhada na solução que eu tinha proposto já finalizada e tente entender

 

@JorgeGus tenha sempre em mente que escrevendo assim está usando números mágicos considerando apenas esse arquivo, e nem mesmo esse arquivo, já que por exemplo na hora de gravar o CSV

 

      fprintf(arqcsv, "002,%s,%s,%s,F\n", matr, nome, dtn);

 

está desconsiderando o que possa ter lá no arquivo de entrada e assumindo que o primeiro campo é 002 e o último é F e na hora de separar os campos está considerando os números FIXOS das colunas.

 

Se a matrícula não vier com 8 dígitos ou a letra não for F ou a data estiver diferente já era.  No geral é frágil. Se fosse apenas para converter para CSV considerando os espaços como separadores de campos exceto pelo nome teria algo mais flexível.

 

TESTE sempre o retorno de scanf()

 

 

 

Postado

@arfneto

1 hora atrás, arfneto disse:

 

@JorgeGus tenha sempre em mente que escrevendo assim está usando números mágicos considerando apenas esse arquivo, e nem mesmo esse arquivo, já que por exemplo na hora de gravar o CSV

 

      fprintf(arqcsv, "002,%s,%s,%s,F\n", matr, nome, dtn);

 

está desconsiderando o que possa ter lá no arquivo de entrada e assumindo que o primeiro campo é 002 e o último é F e na hora de separar os campos está considerando os números FIXOS das colunas.

 

Se a matrícula não vier com 8 dígitos ou a letra não for F ou a data estiver diferente já era.  No geral é frágil. Se fosse apenas para converter para CSV considerando os espaços como separadores de campos exceto pelo nome teria algo mais flexível.

 

TESTE sempre o retorno de scanf()

 

 

 

No arquivo pdf postado no primeiro tópico diz claramente que o primeiro e o último campos são fixos, ou seja são premissas do problema, e não faz sentido se preocupar com isso.

 

Se a matrícula vier com 1 ou 2 dígitos vai funcionar perfeitamente, desde que a largura incluindo os espaços em branco esteja também de acordo com a descrição no pdf de 10 caracteres.

 

E sscanf está lendo de uma variável carregada a partir de fgets, então a verificação teria que ser a partir da leitura de fgets, mas acho pouco provável ocorrer um erro nesse caso já que não se trata de uma situação real.

 

Isso não é uma crítica, mas uma pesoa que não sofre de Síndrome de Asperger conseguiria perceber que o nível de exigência não só pode, como deve variar de acordo com a situação que nesse caso é apenas de um exercício, provavelmente de Programação I.

Postado
51 minutos atrás, JorgeGus disse:

E sscanf está lendo de uma variável carregada a partir de fgets, então a verificação teria que ser a partir da leitura de fgets, mas acho pouco provável ocorrer um erro nesse caso já que não se trata de uma situação real

 

É só um arquivo texto. É super esperado o próprio aluno editar o arquivo para fazer mais testes e acabar "comendo" um espaço durante os testes.... Ou aumento o F para FF

 

Ou o instrutor testar com uma óbvia corrupção para ver se o aluno não testou sequer o mínimo. E assim um scanf() com um especificador "%s%s" é super frágil e o retorno deveria ser comparado com 2, o esperado em caso de sucesso. Mesmo para um iniciante que tenha acabo de ler isso no livro:

 

 

Citação

Return Value

On success, the function returns the number of variables filled. In the case of an input failure before any data could be successfully read, EOF is returned.

 

Em português: Em caso de sucesso scanf() retorna o número de variável preenchidas pela leitura. Em caso de erro antes de qualquer transferência EOF é retornado, um valor negativo.

 

A própria primeira linha com erro pode ser um teste proposital.

 

51 minutos atrás, JorgeGus disse:

Isso não é uma crítica, mas uma pesoa que não sofre de Síndrome de Asperger conseguiria perceber que o nível de exigência não só pode, como deve variar de acordo com a situação que nesse caso é apenas de um exercício

 

Testar um mínimo de situações em um programa que vai consumir texto não é algo reservado a experientes profissionais. Programas de produção são claro outra realidade, mas erros básicos de sincronismo não devem ser descartados completamente, como nesse caso óbvio de nunca testar o retorno de scanf().

 

Basta ver aqui no forum quantos programas aparecem toda semana que falham ou entram em loop graças a isso não ser reforçado por quem ensina ou escreve a respeito: O cara lê um número e depois um nome e o scanf() passa reto e o programa do cara dá erro na linha seguinte.

 

O cara não testou o retorno de nenhum dos scanf() e o programa segue adiante para cancelar na próxima linha ou desprezando tudo que o cara achava que o programa iria ler...

 

Outro exemplo

 

Campo1 Campo2 Campo3 Campo4 Campo5
C1 xxxCampo2 OCampo3 o nome pode ter espacos fim O-Camp-o4 Campo5-f
002 999912012435 Nilo Pontes Sousa 17/02/2000 F
002 21910420 Miguel Veiga Carrilho 26/11/1997 F
002 31813713 Teresinha Fragoso Fontinha 14/01/1997 F
002 41615446 Jordan Belchiorinho Lagos 02/09/1996 F
002 52011977 Iara Quinteiro Melancia 14/02/1996 fácil
002 62010992 Neusa Gomide Canario 02/0000004/2002 Teste
002 62010992 Neusa Gomide Canario 02/04..../2002 Teste

 

Deveria gerar

 

Campo1;Campo2;Campo3;Campo4;Campo5
C1;xxxCampo2;OCampo3 o nome pode ter espacos fim;O-Camp-o4;Campo5-f
002;999912012435;Nilo Pontes Sousa;17/02/2000;F
002;21910420;Miguel Veiga Carrilho;26/11/1997;F
002;31813713;Teresinha Fragoso Fontinha;14/01/1997;F
002;41615446;Jordan Belchiorinho Lagos;02/09/1996;F
002;52011977;Iara Quinteiro Melancia;14/02/1996;fácil
002;62010992;Neusa Gomide Canario;02/0000004/2002;Teste
002;62010992;Neusa Gomide Canario;02/04..../2002;Teste

 

51 minutos atrás, JorgeGus disse:

No arquivo pdf postado no primeiro tópico diz claramente

 

O arquivo pdf não foi postado no tópico. Apenas um link e não faz sentido esperar que alguém tenha que fazer dois downloads de arquivos desconhecidos para depois  abrir e entender e ajudar alguém em um forum público. Os dados devem estar no post até onde possível para que outros também possam se beneficiar dos dados se tem um problema semelhante. 

 

Para ficar BEM claro do que estou falando,  fiz o download agora e aqui está o conteúdo daquele arquivo:

 

image.png.c63ec88206aaea09c7f129ce84f7bb56.png

 

 

Acha mesmo que o autor @Weverson Meirelesnão podia ter postado isso aqui. @JorgeGus?

 

E agora vendo que os dados são de formato fixo e tabulares não vejo razão para consumir como texto... Se ele tivesse postado isso inicialmente eu teria talvez mostrado uma maneira melhor para consumir isso.

 

De todo modo o programa como eu expliquei é mais flexível e está mais no caminho que algo para transformar texto em CSV para situações genéricas mais próximas da realidade de arquivos CSV.

 

Considere algo assim

 

#include <stdio.h>
#include <string.h>

int main(void)
{
    const char dlm     = ';';                      // o delimitador
    FILE*      arquivo = fopen("ARQ01.txt", "r");  // o arquivo
    FILE*      csv = fopen("teste.txt", "w");  // o arquivo
    if (arquivo == NULL) return -1;

    char  frase[2000];
    char* p = fgets(frase, 2000, arquivo);

    while (p != NULL)
    {
        // procura o primeiro branco
        while (*p != 0)
        {
            if (*p != ' ')
                p = p + 1;  // avanca: não e branco
            else
            {
                *p = dlm;    // troca pelo delimitador   [1]
                p  = p + 1;  // avanca
                break;
            }
        };
        // se saiu sem achar o branco o arquivo
        // // tem problemas: cancela
        if (*p == 0)
        {
            fclose(arquivo);
            return -2;
        };

        // procura o segundo branco
        while (*p != 0)
        {
            if (*p == ' ')
            {
                *p = dlm;  // troca                      [2]
                p  = p + 1;
                break;  // sai do loop
            }
            p = p + 1;  // avanca
        };
        // se saiu sem achar o branco o arquivo
        // // tem problemas: cancela
        if (*p == 0)
        {
            fclose(arquivo);
            return -3;
        };

        // agora tem o lance do nome que pode ter varios
        // brancos entao o fácil: seguir pela direita
        int fim = strlen(frase) - 1;
        // apaga provavel '\n' no fim da linha
        if (frase[fim] == '\n') p = p - 1; 
        p  = frase + fim;
        // procura o primeiro branco para a esquerda
        while (*p != 0)
        {
            if (*p == ' ')
            {
                *p = dlm;  // troca                      [3]
                p  = p - 1;
                break;  // sai do loop
            }
            p = p - 1;  // avanca
        };
        if (p == frase)
        {   // erro: falta um campo ao menos
            fclose(arquivo);
            return -4;
        };
        // agora a data
        while (p != frase)
        {  // procura para tras ate o inicio
            if (*p == ' ')
            {
                *p = dlm;  // troca
                break;     // sai do loop
            }
            p = p - 1;  // volta uma letra
        }
        // se chegou ate o comeco entao não achou nenhum branco
        // e o arquivo esta zoado: cancela
        if (p == frase)
        {   // erro: falta um campo
            fclose(arquivo);
            return -5;
        };

        // tudo certo! Entao mostra essa linha
        fprintf(csv,"%s", frase);
        printf("%s", frase);
        p = fgets(frase, 2000, arquivo);  // le a proxima

    };  // while()
    fclose(arquivo);
    return 0;
}

 

Que importaria os dados considerando qualquer largura de campo.

 

De volta ao exemplo

 

Para dados tabulares como esses do programa é mais simples usar registros e abrir o arquivo como binário. E usar simplesmente fread()

 

E considerando o layout apresentado no arquivo PDF os exemplos que eu postei estão todos errados, assim como o código do autor @Weverson Meirelese seus exemplos postados, @JorgeGus . O arquivo de entrada não é um arquivo texto e tem registros de tamanho fixo de 49 o primeiro e 89 os seguintes, sem delimitador. Isso considerando a misteriosa coluna 4 do cabeçalho. Uma bobagem. 

 

Onde está o campo 7 nos registros? Onde está o campo 4 no cabeçalho? 
 

Os dados apresentados pelo autor não correspondem ao layout apresentado pelo próprio autor no tópico #3 :( e o PDF não foi postado. Me arrependo de ter tentado ajudar...

 

 

 

 

 

 

 

 

 

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...