You’re not stopping file processing

Asked

Viewed 52 times

2

Why aren’t you stopping the comparison?

/*7.    Faça um programa que leia uma sequência de nomes no formato “nome sobrenome” e armazene-os em um arquivo texto.
 A lista de nomes termina com um nome igual ao ponto.*/

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

char const FIM[] = ".";

int main()
{
    FILE *arq;
    char nomeS[70];
    char *ret;

    arq = fopen("arquivoGerado07.txt","w");

    puts("Insira um nome e sobrenome: ");
    ret = fgets(nomeS,sizeof(nomeS), stdin);

    while(strcmp(FIM,nomeS) != 0)
    {
        fputs(ret,arq);
        puts("Insira um nome e sobrenome: ");
        ret = fgets(nomeS,sizeof(nomeS),stdin);
    }
    fclose(arq);

    return 0;
}

2 answers

1

After reading the string with fgets() remove from the '\n'.

ret = fgets(nomeS,sizeof(nomeS), stdin);
if (ret == NULL) /* erro */;
nomelen = strlen(nomeS);
if (nomelen == 0) /* erro estranho */;
if (nomeS[nomelen - 1] == '\n') {
    nomeS[--nomelen] = 0; /* remove '\n' e actualiza nomelen */
}
  • If this code runs on a Windows platform, still only one \n will stop at variable? (instead of a \r\n for example? What if the stream entry is not the stdin, and yes a file whose line break is a \r\n?

  • P.S. I confirmed here that he reads yes the \r (in archives, at least I don’t know about the stdin).

  • Another problem: if the string read 69 characters it will not include the \n at the end. See that thread for more details. Therefore, it is best to only run this last line if it is confirmed that the nomeS[nomelen-1] is even a \n.

  • 1

    If the file was opened in text mode ("r", "r+", ...) he doesn’t read the '\r' (the stdin is opened in text mode).

  • Thank you for the 69 character note. Modified snippet.

  • Thanks for the clarification! I was in doubt because, second that answer, if the GNU compiler is used - which makes no difference between binary mode and text mode - on a Windows platform, \r would be read independently of the mode (again, in files, did not know if this applied to stdin or not).

  • 1

    The problem with this answer is not so much the compiler as the library, that is, mixing a Windows compiler with a Linux library. Note that fputc('\n', arquivo); can write 2 bytes in Windows, if arquivo opened in text mode.

Show 2 more comments

0

According to that documentation, the fgets includes the line break read from stream (i.e. when you give Enter) on their way out - unlike gets, not included. Thus, the string read will never be equal to "." - at most will be ".\n", ".\r" or ".\r\n", depending on the platform (Note: at least this occurs in reading files - not sure if reading the stdin whether or not it takes into account the standard line break of the platform or whether it uses \n at all times).

For the purposes of your exercise, I believe the best way out is to use gets despite the danger of overflow:

ret = gets(nomeS);

In practice, however, the ideal would be either normalize the value read or test by the 3 variants, which is easier (I have little practical experience in C, so I can’t help in this direction).

  • 1

    That one -1 is because I suggest using a gets? Or is there something else wrong with the answer?

Browser other questions tagged

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