File In C language

1

I have a file In this format:

link (link to download the file read);

[105][32][55][10][32][32][32][32][32][32][32][32][32][32][32][32][32][32][32][32][32][82][101][108][101][97][115][101]...

I need to read the data in this format:

105 32 55 10 32 32 32 32 32...[32][32][32][32][32][32][32][32][32][32][32][32][82][101][108][101][97][115][101]...

I'm using the code trick:

while( c != EOF) {

    fscanf(ler, "%c", &c);
    fscanf(ler, "%d", &num);
    fscanf(ler, "%c", &a);

    fprintf(traduzido, "%d ", num);

}

But looping never closes, I'm also using this:

while(fscanf(ler, "%c", &c)  && fscanf(ler, "%d", &num)   &&   fscanf(ler, "%c", &a)   != EOF) {

    fprintf(traduzido, "%d ", num);

}

But it does not stop reading the file, it always goes from two to three lines.

What is the error and why of the error? How can I read this file and leave it as I want, if I have an easier way?

Look at the code completely:

int main(void)

int num;
char c;

FILE *ler;
FILE *traduzido;

ler = fopen("readme.code.txt", "r");
traduzido = fopen("traduzido.txt", "w");

if(ler == NULL || traduzido == NULL) {
    printf("Erro Na aberura do Arquivo");
}

while(1) {
    if (fscanf(ler, "%c", &c) <= 0){
        break;
    }

    fscanf(ler, "%d", &num);
    fscanf(ler, "%c", &c);

    fprintf(traduzido,"%d ", num);
}

while(fscanf(traduzido, "%d", &num) != EOF) {
    printf("%c", num);
}
system("pause");
    
asked by anonymous 21.11.2017 / 22:34

2 answers

3

The fscanf returns:

  • The number of elements read and assigned to variables
  • 0 if you could not associate any element
  • EOF , which corresponds to -1 if it has reached the end of the file

In this case and assuming that the structure of your file is always [numero] you can test specifically for values equal to or less than 0 in the first fscanf :

while(1) { //agora while infinito
    if (fscanf(ler, "%c", &c) <= 0){
        break; //se não conseguiu ler o próximo [ termina o while
    }

    fscanf(ler, "%d", &num);
    fscanf(ler, "%c", &c);

    fprintf(traduzido, "%d ", num);
}

Note that you can use the same variable c because you are not doing anything with it.

If you want to play safe, and be resistant to changes in formats you can test all fscanf :

while(1) {
    if (fscanf(ler, "%c", &c) <= 0 ||  
        fscanf(ler, "%d", &num) <= 0 || 
        fscanf(ler, "%c", &c) <= 0){
        break;
    }

    fprintf(traduzido, "%d ", num);
}

Test the program by switching% of% by% with% to make it easier to see:

Testwithsuggestedfilefprintf:

Edit:

Fortherestoftheprogramthathastheproblemisreadingafilethatwasopenedforwriting.

Closethefileprintfafterwritingandopenitagainforreading:

while(1){if(fscanf(ler,"%c", &c) <= 0){
        break;
    }

    fscanf(ler, "%d", &num);
    fscanf(ler, "%c", &c);

    fprintf(traduzido,"%d ", num);
}

fclose(traduzido); //fechar a escrita
traduzido = fopen("traduzido.txt", "r"); //agora abrir para leitura

while(fscanf(traduzido, "%d", &num) != EOF) {
    printf("%c", num);
}

However, it was more efficient to simply write the contents of what is being read directly on the screen, instead of using the file readme.code.txt to write and then to read:

while(1) {
    if (fscanf(ler, "%c", &c) <= 0){
        break;
    }

    fscanf(ler, "%d", &num);
    fscanf(ler, "%c", &c);

    fprintf(traduzido,"%d ", num); //grava no arquivo a tradução
    printf("%c",num); //e simultaneamente escreve na tela a conversão
}

It is much more efficient and simple.

    
22.11.2017 / 00:03
2

I came here to just show you more possibilities to @Isac response , using scanf resources to remove this formatting.

To begin with, I found it odd to read the value of a character in a temporary variable to ignore. I then remembered that somewhere I had seen something about reading that did not fill the values (see documentation ), the reading indicated by the * modifier; for example, scanf("%*c") will read a character from the entry and ignore it. So I did a test on this reading by ignoring characters:

#include <stdio.h>

int main(void) {
    int i;

    scanf("%*c%d%*c", &i);
    printf("%d\n", i);

    return 0;
}

For input [123] , the result was 123 , as expected.

So I remembered that you can skip the actual formatting of the input. Simply put the desired characters to be ignored on the left before the %d , and the characters to ignore on the right after %d . In this case, the format would be [%d] , because I want to ignore the open brackets [ on the left and the close brackets ] on the right:

#include <stdio.h>

int main(void) {
    int i;

    scanf(" [%d]", &i);
    printf("%d\n", i);

    return 0;
}

I tested for input [145] , getting 145 as output. If I paid attention, I put a space at the beginning of the format string to avoid conflicts with line breaks, since my test involved a number in brackets per line. You can view my full test on ideone .

So this means that the reading proposed by @Isac could be replaced by one of these options.

Original:

while(1) {
    if (fscanf(ler, "%c", &c) <= 0){
        break;
    }

    fscanf(ler, "%d", &num);
    fscanf(ler, "%c", &c);

    fprintf(traduzido,"%d ", num); //grava no arquivo a tradução
    printf("%c",num); //e simultaneamente escreve na tela a conversão
}

Proposal 1, with %*c :

while(1) {
    if (fscanf(ler, "%*c%d%*c", &num) <= 0){
        break;
    }

    fprintf(traduzido,"%d ", num); //grava no arquivo a tradução
    printf("%c",num); //e simultaneamente escreve na tela a conversão
}

Proposal 2, with format string ignoring brackets:

while(1) {
    if (fscanf(ler, "[%d]", &num) <= 0){
        break;
    }

    fprintf(traduzido,"%d ", num); //grava no arquivo a tradução
    printf("%c",num); //e simultaneamente escreve na tela a conversão
}
    
22.11.2017 / 12:21