Path: csiph.com!eternal-september.org!feeder.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Keith Thompson Newsgroups: comp.lang.c Subject: Re: Piece of code to read and process data from a file, separating chars and ints Date: Fri, 23 Dec 2016 14:10:05 -0800 Organization: None to speak of Lines: 60 Message-ID: References: <0fb61ff9-91e4-4001-b99d-6cc1ce28dc6f@googlegroups.com> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Injection-Info: mx02.eternal-september.org; posting-host="df4a13e992574b38b1b7cd38c2b29037"; logging-data="15409"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+KcU2aYDQkCb/FJ6y0awzV" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux) Cancel-Lock: sha1:NfJtydGJHretX9ACSs1GMYSKjLA= sha1:zj7qq1yEH3Jq+cEvnByFnQEu8EM= Xref: csiph.com comp.lang.c:100095 Alla _ writes: [...] > (2) Attn. Richard: I have disobeyed you, Sir ) My apologies. I have > implemented the dynamic memory allocation to follow one of the > headsups suggested by Keith. This is the only one feature that is > “sort of” more advanced, but I do believe it is necessary for this > program, not only because the lines might be arbitrarily long, but > because it is a great practice, and it is not such a fancy feature > after all. I'm sorry if my advice led you astray. What I meant to suggest (and I think I did, but I'm too lazy to go back and check) is that if you want to handle arbitrarily long lines, you should implement a function to do that *separately*, not as part of your large CSV-processing program. For example, you might write a function: char *get_line(FILE *in); (Note: not "getline", there's a POSIX function by that name) that returns a pointer to an allocated string. Internally, get_line() would probably use fgets(), malloc(), and realloc(). Implement and debug that function *separately*, using a program that does nothing but call get_line() to read lines from a file. Once you've tested it with as many cases as you can think of (empty lines, short lines, very long lines, multiple calls, correctly handling EOF, correctly handling a trailing line with no '\n'), *then* you can drop that function into your CSV program. As it is, you haven't even written a separate line-reading function. You've created some wrappers around your realloc() calls (which I'm not sure was a useful thing to do), but your allocation logic is mixed up with your input loop. What I think you *should* have done was write your CSV program to use fgets(), handling lines up to, say, 1000 characters, and test it with input data that meets that restriction. And once that works, you could drop in your get_line() function if you insist on doing that extra work. As it is, you have something going wrong that's causing realloc() to fail -- and it's going to be difficult to track down that error. Another observation (I haven't read your entire program): Several of your functions return EXIT_FAILURE and EXIT_SUCCESS to indicate whether they failed or succeeded. That might seem like a good idea, but in my opinion it's poor style. Those values specify the return status of your main program. A common convention is for a function to return an int status, with 0 denoting success and non-0 denoting failure (note that EXIT_SUCCESS is not necessarily 0). Or your functions could return bool if you don't need to distinguish among different kinds of failures. -- Keith Thompson (The_Other_Keith) kst-u@mib.org Working, but not speaking, for JetHead Development, Inc. "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister"