Deutsch   English   Français   Italiano  
<20240617004533.00002093@yahoo.com>

View for Bookmarking (what is this?)
Look up another Usenet article

Path: ...!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: Michael S <already5chosen@yahoo.com>
Newsgroups: comp.lang.c
Subject: Re: Whaddaya think?
Date: Mon, 17 Jun 2024 00:45:33 +0300
Organization: A noiseless patient Spider
Lines: 156
Message-ID: <20240617004533.00002093@yahoo.com>
References: <666ded36$0$958$882e4bbb@reader.netnews.com>
	<20240616015649.000051a0@yahoo.com>
	<v4lm16$3s87h$4@dont-email.me>
	<v4lmso$3sl7n$1@dont-email.me>
	<v4lr0m$3tbpj$1@dont-email.me>
	<8734pd4g3s.fsf@nosuchdomain.example.com>
	<v4ltuj$3trj2$1@dont-email.me>
	<20240616111134.00001f18@yahoo.com>
	<v4ma0a$3vrne$1@dont-email.me>
	<20240616123850.00002d93@yahoo.com>
	<v4md99$ebo$1@dont-email.me>
	<20240616143143.00001d8a@yahoo.com>
	<v4n0rv$41ir$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit
Injection-Date: Sun, 16 Jun 2024 23:45:46 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="80e0c2bced6a7a3e7e096b2e292da6ed";
	logging-data="3776572"; mail-complaints-to="abuse@eternal-september.org";	posting-account="U2FsdGVkX1+Kw6bmDryeFZcBXrIPE2Nj1FxwiuPamrY="
Cancel-Lock: sha1:gupaCcRy5DpyMjyfA0D+TuGAtic=
X-Newsreader: Claws Mail 4.1.1 (GTK 3.24.34; x86_64-w64-mingw32)
Bytes: 6465

On Sun, 16 Jun 2024 17:37:34 +0200
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:

> On 16.06.2024 13:31, Michael S wrote:
> > On Sun, 16 Jun 2024 12:03:21 +0200
> > Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
> >   
> >> On 16.06.2024 11:38, Michael S wrote:  
> >   
> >>
> >> Again; which ones?
> >>
> >> Janis
> >>  
> >>> [...]    
> >>
> >>  
> > 
> > The main misconceptions are about what is returned by fgets() and by
> > realloc().
> > fgets() returns its first argument in all cases except EOF or FS
> > read error. That includes the case when the buffer is too short to
> > accommodate full input line.  
> 
>    fgets() return s on success, and NULL on error or when end
>            of file occurs while no characters have been read.
> 
> I am interested in the success case, thus "fgets() != NULL".
> The buffer size is controlled by the second function parameter.
> 
> > 
> > With realloc() there are two issues:
> > 1. It can sometimes return its first argument, but does not have
> > to. In scenario like yours it will return a different pointer quite
> > soon. 2. When realloc() returns NULL, it does not de-allocate its
> > first argument.
> > 
> > The second case, of course, is not important in practice, because in
> > practice you're very unlikely to see realloc() returning NULL, and
> > if nevertheless it did happen, you program is unlikely to survive
> > and give meaningful result anyway. Still, here on c.l.c we like to
> > pretend that we can meaningfully handle allocation failures.  
> 
> You may provide "correct" code (if you think mine is wrong). Or just
> inspect how it behaves; here's the output after two printf's added:
> 
> $ printf "123 456 789 101112 77 88 99 101 999" | realloc
> +++>123 456 78<+++
> ===>123 456 78<===
> +++>9 101112 7<+++
> ===>123 456 789 101112 7<===
> +++>7 88 99 10<+++
> ===>123 456 789 101112 77 88 99 10<===
> +++>1 999<+++
> ===>123 456 789 101112 77 88 99 101 999<===  
> 123 456 789 101112 77 88 99 101 999
> 
> The +++data+++ is the chunk read, and the ===data=== is the overall
> buffer content, and the final line again the result (as before, with
> the added newline as documented for puts()).
> 
> Even though my code is just an "ad hoc test code" to demonstrate the
> procedure I outlined - and as such test code certainly lacking quite
> some error handling and much more - it does exactly what I intended it
> to do, and what I've implemented according to what I read in the man
> pages. I cannot see any "misconception", it does what was _intended_.
> 
> There's indeed one point that I _deliberately_ ignored for the test
> code; actually the point you mentioned as "not important in practice".
> 
> Again: You may provide "correct" code (if you think mine is "wrong"),
> or "better" code, usable for production instead of a test code.
> 
> But your tone and statements were (as observed so often) inadequate;
> I quote from your post that started the subthread:
> "However it looks unlikely that it does what you meant for it to do."
>

Did you consider that, may be, your understanding of C library is
inadequate?


> It does exactly what I meant to do (as you can see in the logs above).
>
> Janis
> 

The only thing I see in your logs is that your testing skills are on par
with your coding skills.

I am not quite sure what your code is supposed to do.
However, my impression was that we wanted to read text file line by
line and to process lines separately. You code certainly does not do
it. As I said above it contains several mistakes, including one that is
particularly serious and hard to diagnose - a use of de-allocated
buffer.

Below is an example of how to do it correctly.
It's not the only possible method, but any correct method would have
similar complexity.


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

int main(void)
{
  const int sz_incr = 10;
  size_t bufsz = 32;
  char* buffer = malloc(bufsz);
  if (!buffer) {
    perror("malloc()");
    return 1;
  }

  size_t rdi = 0;
  int err = 0;
  for (size_t line_i = 1; ;) {
    buffer[bufsz-1] = 1; // set guard
    if (!fgets(&buffer[rdi], bufsz-rdi, stdin))
      break; // eof or error

    if (buffer[bufsz-1] != 0 || buffer[bufsz-2] == '\n') {
      // Full line - we can process it here
      // As an example, let's print our line as hex
      printf("%10zu:", line_i);
      size_t len = (char*)memchr(&buffer[rdi], '\n',
    bufsz-rdi-1)+1-buffer; for (size_t i = 0; i < len; ++i)
        printf(" %02x", (unsigned char)buffer[i]);
      printf("\n");
      rdi = 0;
      ++line_i;
    } else {
      // line is longer then bufsz-1
      rdi = bufsz-1;
      bufsz += sz_incr;
      char* tmp = realloc(buffer, bufsz);
      if (!tmp) {
        perror("realloc()");
        err = 1;
        break;
      }
      buffer = tmp;
    }
  }

  free(buffer);
  if (ferror(stdin)) {
    perror("fgets(stdin)");
    err = 2;
  }
  return err;
}