Path: csiph.com!x330-a1.tempe.blueboxinc.net!newsfeed.hal-mli.net!feeder3.hal-mli.net!newsfeed.hal-mli.net!feeder1.hal-mli.net!border3.nntp.dca.giganews.com!Xl.tags.giganews.com!border1.nntp.dca.giganews.com!nntp.giganews.com!local2.nntp.dca.giganews.com!nntp.earthlink.com!news.earthlink.com.POSTED!not-for-mail NNTP-Posting-Date: Wed, 19 Oct 2011 18:02:33 -0500 Message-ID: <4E9F570F.5A16@mindspring.com> Date: Wed, 19 Oct 2011 19:02:39 -0400 From: pete Reply-To: pfiland@mindspring.com Organization: PF X-Mailer: Mozilla 3.04Gold (WinNT; I) MIME-Version: 1.0 Newsgroups: comp.lang.c Subject: Re: Analogue of ReadLine() in C References: <91b648bd-bf1e-4093-97a4-77b7300a94c5@c1g2000vbw.googlegroups.com> Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Lines: 178 X-Usenet-Provider: http://www.giganews.com NNTP-Posting-Host: 4.156.228.190 X-Trace: sv3-SMc/vGjPIWO/FDIaB9+p1HL120RL8QubPJ9LagranneZT5x7DMpKZyIObzbaS+JifxFyW2MQOxCBIgY!VuoaPSd8lW44bdVe6skWVhr8xP5VEtAB2BoDqFprBsfFauBPFjxfvalT1GEytKoWpMSz52v71fyw!MXLz8H/UwPA= X-Abuse-and-DMCA-Info: Please be sure to forward a copy of ALL headers X-Abuse-and-DMCA-Info: Otherwise we will be unable to process your complaint properly X-Postfilter: 1.3.40 X-Original-Bytes: 5750 Xref: x330-a1.tempe.blueboxinc.net comp.lang.c:11894 =?UTF-8?B?0JzQsNC60YHQuNC8INCk0L7QvNC40L0=?= wrote: > > I need function similar to ReadLine() in any other language. > The program below fails[1] when data more then LAG_SIZE is passed > > #include > #include > #include > #include > > char * read_line(void) > { > bool read_more = true; > enum { LAG_SIZE = 32 }; > char *return_buf = NULL; > char *new_line_pos = NULL; > char tmp_buf[LAG_SIZE] = {'\0'}; > size_t size = 0; > while (read_more && fgets(tmp_buf, LAG_SIZE, stdin)){ > char *tmp_realloc; > size += LAG_SIZE; > tmp_realloc = realloc(return_buf, size); > if (!tmp_realloc){ > free(return_buf); > return_buf = NULL; > break; > } > return_buf = tmp_realloc; > memset(return_buf + size - LAG_SIZE, '\0', LAG_SIZE); > new_line_pos = strchr(tmp_buf, '\n'); > if (new_line_pos){ > *new_line_pos = '\0'; > read_more = false; > } > strcat(return_buf, tmp_buf); > memset(tmp_buf, '\0', LAG_SIZE); > } > return return_buf; > } > > void loop(void) > { > bool repeat = true; > while (repeat){ > char *command; > printf("Enter> "); > command = read_line(); > if (command && !strcmp(command, "exit")) > repeat = false; > free(command); > } > } > > int main(void) > { > loop(); > return 0; > } > > [1]: *** glibc detected *** ./a.out: realloc(): invalid next size: > 0x0804b008 *** /* BEGIN read_line_test.c */ #include #include #include #include void loop(void); int read_line(char **lineptr, size_t *n, FILE *stream, size_t *size); int main(void) { loop(); return 0; } void loop(void) { int rc; char *command = NULL; size_t n = 0; do { printf("Enter> "); rc = read_line(&command, &n, stdin, NULL); } while (rc > -1 && strcmp(command, "exit")); free(command); } int read_line(char **lineptr, size_t *n, FILE *stream, size_t *size) { int rc; size_t count = 0; size_t min = 2; while ((rc = getc(stream)) != EOF || !feof(stream) && !ferror(stream)) { if (++count == (size_t)-2) { if (rc != '\n') { (*lineptr)[count - 1] = (char)rc; (*lineptr)[count++] = '\0'; } else { (*lineptr)[count - 1] = '\0'; } break; } if (++min > *n) { void *p; size_t max; size_t next; for (next = min ^ min - 1; min > next; ++next) { next *= 2; } do { max = next; next = (max - min) / 2 + min; p = realloc(*lineptr, max); } while (p == NULL && max != min); if (p == NULL) { if (*n > count) { if (rc != '\n') { (*lineptr)[count - 1] = (char)rc; (*lineptr)[count++] = '\0'; } else { (*lineptr)[count - 1] = '\0'; } } else { ungetc(rc, stream); --count; if (*n != 0) { (*lineptr)[count++] = '\0'; } } if (size != NULL) { *size = count; } count = 0; break; } else { *lineptr = p; *n = max; } } if (rc != '\n') { (*lineptr)[count - 1] = (char)rc; } else { (*lineptr)[count - 1] = '\0'; break; } } if (rc != EOF || !feof(stream) && !ferror(stream)) { rc = INT_MAX > count ? count : INT_MAX; } else { if (*n > count) { (*lineptr)[count++] = '\0'; } } if (size != NULL && rc != 0) { *size = count; } return rc; } /* END read_line_test.c */ -- pete