File In C language

Asked

Viewed 222 times

1

I have a file in this following format:

https://mega.nz/#! Dwxxrizk (link to download read file);

[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 snippet:

while( c != EOF) {

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

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

}

but the looping never ends, I’m also using this:

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

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

}

but he won’t 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 in the way I want, if there is an easier way?

Look at the code in full:

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");
  • The correct is to check the output of the scanf. I’ve answered a similar question to that one, but obviously it’s lost in the sea of answers.

  • In this answer I talk a little about the return of scanf: https://answall.com/a/253415/64969; I believe it will help

  • By the way, this flow could be treated as the flowchart of this question: https://answall.com/a/251865/64969; "a": leitura, "b": if the end of the file happened, the loop ends

  • I took a look, but with you, I read to the last item of the file over there, it’s in a looping

  • while( fscanf(ler,"%c", &c) != EOF ){&#xA; &#xA; fscanf(ler, "%d", &num);&#xA; fscanf(ler, "%c", &c);&#xA; fprintf(traduzido, "%d ", num);&#xA;&#xA; } the damn code shouldn’t stop ? it gets looping

  • Calm down, young man. In answer, I put in condition if the return was positive. In the linked documentation, you have said that, in case of this error, you would return a negative value (not specifying which negative value). In case, EOF is a possible negative value in 2 billion existing. Perhaps exchange this difference for a > 0 or >= 0 (I don’t remember what the 0 return means...) is better

  • The problem is that never returns < 0, always positive, I honestly do not know the problem of my check, already angry here, will never

  • Are ellipsis literal or are they just a stylistic resource to indicate that there may be more to it? If this is the second option, try making an example of minimal input and output to try playing. For example, 3 numbers would be enough

  • Swears you uploaded the file to the mega uploads? Why not have a smaller and viable example?

Show 4 more comments

2 answers

3


The fscanf return:

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

In this case and assuming that the structure of your file is always [numero] may specifically test at or below 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’re not doing anything to her.

If you want to play it safe, and become 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 of the program changing fprintf for printf to be easier to see:

inserir a descrição da imagem aqui

Test with the suggested file readme.code.txt :

inserir a descrição da imagem aqui

Edit:

For the rest of the program that has the problem is reading a file that has been opened for writing.

Close the file traduzido after writing and open it again for reading:

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 more efficient was simply writing the content of what is being read directly on the screen, instead of using the file traducao 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’s much more efficient and simple.

  • Hmmmm, I remembered something interesting.. %*c reads the information and discards it, so you wouldn’t even need to put the variable c at stake

  • The problem is that it passes, for example, it reads until the last number but then it starts to come some repeated, it stops reading the file and is coming junk from memory

  • 1

    @Jeffersonquesado Yes is indeed an interesting option that optimizes even more resources

  • @Fernando File has line breaks ? How exactly is the file contents?

  • Without line break, this is the end of the file, [101][100][46]... already the translated file comes so -> 101 100 46 99 111 109 47 100 101 108... it for after about 10 lines, type in thin file read, has a space, per exe, [101][100][46]...............................................

  • 1

    @Fernando Testei with the [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] that was in the question and worked perfectly. You can ask the question the exact contents of the file, so I can test and reproduce the problem ?

  • I put a link with the file

  • @Fernando asks for key to access the file, better maybe put in Pastebin or other similar alternative.

  • https://mega.nz/#! blAGiBrD! aYphUoyfUbwlF8wiAu25QsewmE2aD0merkIpWapDt_Y tries that

  • @Fernando worked well. There is something else that should not be doing correctly, maybe in the rest of the program. If you want I can include a print also of the execution with this file.

  • Post yes then, must be problem here if there worked

  • @Fernando See in my edition how it worked. Note however that writing each number read on the screen, it still takes 4 seconds to finish.

  • I am trying to solve here, let me check the dnv code, try to print so prinf("%c", in a) this is a text, if you are curious to see '-'

  • Look at my code there on the question, help me find the mistake ?

  • @Fernando Editei the answer, already contemplating the code that placed.

  • Man I love you, vlw even, it was just that and I did not understand, vlw by patience, truth, I could print right there... but anyway I would have to read later, this was only the first part, I have but a couple, now the mission is to put the line number

  • I will make a response based on your merging with the results I obtained in this experiment: https://ideone.com/3WFf96

  • @Jeffersonquesado Sounds like a good idea. The more answers, the more possible solutions and more content we offer to the community! :)

  • Now I got the result I wanted: https://ideone.com/FeohUm knew that it was possible to ignore formatting marks of an arbitrary entry through the scanf

Show 14 more comments

2

I just came here to show you a lot of possibilities reply from @Isac, using resources from scanf to remove this formatting.

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

#include <stdio.h>

int main(void) {
    int i;

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

    return 0;
}

To the entrance [123], the result was 123, as expected.

Then I remembered that it is possible to ignore the actual formatting of the input. Just put the desired characters to be ignored on the left before the %d, and the characters to be ignored on the right after the %d. In this case, the format would be [%d], because I wish to ignore the clasps [ to the left and the clasps ] on the right:

#include <stdio.h>

int main(void) {
    int i;

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

    return 0;
}

I tested for the entrance [145], getting 145 as a way out. If you pay attention, I put a space at the beginning of the format string to avoid conflicts with line breaks, as my test involved a number between brackets per line. You can see my complete test on ideone.

So this means that the @Isac reading 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
}
  • 1

    All methods work as expected, that last ["%d"] is probably the most efficient, since it doesn’t need more variables and reading, thanks for the help as well

  • To talk about efficiency is complicated, I would have to test a lot... I can try to update later this answer with a corpus suitable for the benchmark

  • You don’t need all this work no, Rlx

  • Young man I know I’m already asking too much, but there’s no way you give me a light, I’m trying to do this look [https://lh3.googleusercontent.com/VxB5_DGTFpef1uuuuwhFreh0cqabgfnC5EyWTSk1PourwcHyY9WCGQuD5Y-eGRQo6n_qsUmYhWdQPJOXeQHicB=w1680-h917] But I can’t get you to stay in the first line, I’m generating 80 to 140 MB of text, nothing to see what I’m doing. (I put the Google Drive photo)

  • Young man, by your description gave a lazy to see... not to mention that my computer is not helping at all, nor can I work without having to restart every 30 min

  • All right then

  • 1

    I got it, I got it

Show 2 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.