By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,937 Members | 1,140 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,937 IT Pros & Developers. It's quick & easy.

slurping in binary data

P: n/a
1 0001000000000000001
2 0001000000000000001
3 10000011001000000000000001
4 10000011001000000000000001
5 10000011001000000000000001
6 10000011001000000000000001
7 10000011001000000000000001
8 10000011001000000000000001
9 10000011001000000000000001
10 10000011001000000000000001
11 100000001111100
12 100000001111100
13 100000001111100
14 1000001110110111100000000000001
15 1000001110110111100000000000001
16 1000001110110111100000000000001
17 1000001110110111100000000000001
18 1000001110110111100000000000001
19 1000001110110111100000000000001
20 0001000000000000001

1
2
*****
*****
*****
*****
*****
*****
*****
***** 10
************ 11
************
************
***** *** 14
***** ***
***** ***
***** ***
***** ***
***** ***
20

3W, 12 B, 5W
1000 0000111 1100

If I wanted to suck in the above 20 lines without line numbers, spaces,
carriage returns, line feeds, or anything that is not a zero, one or EOF,
how would I do it?

Thanks in advance,

--
George

Terrorist attacks can shake the foundations of our biggest buildings, but
they cannot touch the foundation of America. These acts shatter steel, but
they cannot dent the steel of American resolve.
George W. Bush

Picture of the Day http://apod.nasa.gov/apod/
Nov 18 '08 #1
Share this Question
Share on Google+
30 Replies


P: n/a
On 18 Nov, 05:44, George <geo...@example.invalidwrote:
1 *0001000000000000001
2 *0001000000000000001
3 *10000011001000000000000001
4 *10000011001000000000000001
5 *10000011001000000000000001
6 *10000011001000000000000001
7 *10000011001000000000000001
8 *10000011001000000000000001
9 *10000011001000000000000001
10 *10000011001000000000000001
11 *100000001111100
12 *100000001111100
13 *100000001111100
14 *1000001110110111100000000000001
15 *1000001110110111100000000000001
16 *1000001110110111100000000000001
17 *1000001110110111100000000000001
18 *1000001110110111100000000000001
19 *1000001110110111100000000000001
20 *0001000000000000001

1
2
* *****
* *****
* *****
* *****
* *****
* *****
* *****
* ***** 10
* ************ 11
* ************
* ************
* ***** * **** 14
* ***** * ****
* ***** * ****
* ***** * ****
* ***** * ****
* ***** * ****
20

3W, 12 B, 5W
1000 0000111 1100

If I wanted to suck in the above 20 lines without line numbers, spaces,
carriage returns, line feeds, or anything that is not a zero, one or EOF,
how would I do it?
assuming you mean the twenty lines at the beginning. Would fgets()
followed by

int line_num;
char data[32];

fscanf (line, "%d %32s", &line_num, data);

do the job?

--
Nick Keighley

Nov 18 '08 #2

P: n/a
On Tue, 18 Nov 2008 00:59:20 -0800 (PST), Nick Keighley wrote:
On 18 Nov, 05:44, George <geo...@example.invalidwrote:
>1 *0001000000000000001
2 *0001000000000000001
3 *10000011001000000000000001
4 *10000011001000000000000001
5 *10000011001000000000000001
6 *10000011001000000000000001
7 *10000011001000000000000001
8 *10000011001000000000000001
9 *10000011001000000000000001
10 *10000011001000000000000001
11 *100000001111100
12 *100000001111100
13 *100000001111100
14 *1000001110110111100000000000001
15 *1000001110110111100000000000001
16 *1000001110110111100000000000001
17 *1000001110110111100000000000001
18 *1000001110110111100000000000001
19 *1000001110110111100000000000001
20 *0001000000000000001

1
2
* *****
* *****
* *****
* *****
* *****
* *****
* *****
* ***** 10
* ************ 11
* ************
* ************
* ***** * **** 14
* ***** * ****
* ***** * ****
* ***** * ****
* ***** * ****
* ***** * ****
20

3W, 12 B, 5W
1000 0000111 1100

If I wanted to suck in the above 20 lines without line numbers, spaces,
carriage returns, line feeds, or anything that is not a zero, one or EOF,
how would I do it?

assuming you mean the twenty lines at the beginning. Would fgets()
followed by

int line_num;
char data[32];

fscanf (line, "%d %32s", &line_num, data);

do the job?
Why fgets before scanf?

The better data set is:

1 0001000000000000001
2 0001000000000000001
3 10000011001000000000000001
4 10000011001000000000000001
5 10000011001000000000000001
6 10000011001000000000000001
7 10000011001000000000000001
8 10000011001000000000000001
9 10000011001000000000000001
10 10000011001000000000000001
11 100000001111100000000000001
12 100000001111100000000000001
13 100000001111100000000000001
14 1000001110110111100000000000001
15 1000001110110111100000000000001
16 1000001110110111100000000000001
17 1000001110110111100000000000001
18 1000001110110111100000000000001
19 1000001110110111100000000000001
20 0001000000000000001
--
George

The course of this conflict is not known, yet its outcome is certain.
Freedom and fear, justice and cruelty, have always been at war, and we know
that God is not neutral between them.
George W. Bush

Picture of the Day http://apod.nasa.gov/apod/
Nov 18 '08 #3

P: n/a
On Nov 18, 12:59 am, Nick Keighley <nick_keighley_nos...@hotmail.com>
wrote:
On 18 Nov, 05:44, George <geo...@example.invalidwrote:
1 0001000000000000001
2 0001000000000000001
3 10000011001000000000000001
4 10000011001000000000000001
5 10000011001000000000000001
6 10000011001000000000000001
7 10000011001000000000000001
8 10000011001000000000000001
9 10000011001000000000000001
10 10000011001000000000000001
11 100000001111100
12 100000001111100
13 100000001111100
14 1000001110110111100000000000001
15 1000001110110111100000000000001
16 1000001110110111100000000000001
17 1000001110110111100000000000001
18 1000001110110111100000000000001
19 1000001110110111100000000000001
20 0001000000000000001
1
2
*****
*****
*****
*****
*****
*****
*****
***** 10
************ 11
************
************
***** *** 14
***** ***
***** ***
***** ***
***** ***
***** ***
20
3W, 12 B, 5W
1000 0000111 1100
If I wanted to suck in the above 20 lines without line numbers, spaces,
carriage returns, line feeds, or anything that is not a zero, one or EOF,
how would I do it?

assuming you mean the twenty lines at the beginning. Would fgets()
followed by

int line_num;
char data[32];

fscanf (line, "%d %32s", &line_num, data);

do the job?
But he would would fgets() followed by fscanf(), wouldn't that just
suck in one line at a time vs all 20 lines at once? Here is what I
mean. BTW, I used sscanf() and not fscanf().

[cdalten@localhost oakland]$ pwd
/home/cdalten/oakland
[cdalten@localhost oakland]$ more bin.txt
1 0001000000000000001
2 0001000000000000001
3 10000011001000000000000001
4 10000011001000000000000001
5 10000011001000000000000001
6 10000011001000000000000001
7 10000011001000000000000001
8 10000011001000000000000001
9 10000011001000000000000001
10 10000011001000000000000001
11 100000001111100000000000001
12 100000001111100000000000001
13 100000001111100000000000001
14 1000001110110111100000000000001
15 1000001110110111100000000000001
16 1000001110110111100000000000001
17 1000001110110111100000000000001
18 1000001110110111100000000000001
19 1000001110110111100000000000001
20 0001000000000000001
[cdalten@localhost oakland]$ more slurp.c
#include <stdio.h>
#include <stdlib.h>

#define PATH "/home/cdalten/oakland/bin.txt"
#define NUMBER 100
#define BIN 1000
#define MAXFMTLEN 2000

int main(void)
{
FILE *fp;
char pattern[MAXFMTLEN];
char lnumber[NUMBER];
char lbin[BIN];
char line[MAXFMTLEN];

/*int line_num;
char data[32];*/

if ((fp = fopen(PATH, "r")) == NULL ) {
fprintf(stderr, "can't open file\n");
exit(1);
}

sprintf(pattern, "%%%ds %%%ds", BIN-1, NUMBER-1);

while ((fgets(line, MAXFMTLEN, fp)) != NULL ) {
sscanf(line, pattern , lnumber, lbin);
/*fscanf (fp, "%d %32s", &lnumber, lbin);*/
printf("%s\n", lbin);
}

fclose(fp);
return 0;
}

[cdalten@localhost oakland]$ gcc -Wall slurp.c -o slurp
[cdalten@localhost oakland]$ ./slurp
0001000000000000001
0001000000000000001
10000011001000000000000001
10000011001000000000000001
10000011001000000000000001
10000011001000000000000001
10000011001000000000000001
10000011001000000000000001
10000011001000000000000001
10000011001000000000000001
100000001111100000000000001
100000001111100000000000001
100000001111100000000000001
1000001110110111100000000000001
1000001110110111100000000000001
1000001110110111100000000000001
1000001110110111100000000000001
1000001110110111100000000000001
1000001110110111100000000000001
0001000000000000001
[cdalten@localhost oakland]$
Nov 18 '08 #4

P: n/a
On Nov 18, 4:06 am, Chad <cdal...@gmail.comwrote:
On Nov 18, 12:59 am, Nick Keighley <nick_keighley_nos...@hotmail.com>
wrote:
On 18 Nov, 05:44, George <geo...@example.invalidwrote:
1 0001000000000000001
2 0001000000000000001
3 10000011001000000000000001
4 10000011001000000000000001
5 10000011001000000000000001
6 10000011001000000000000001
7 10000011001000000000000001
8 10000011001000000000000001
9 10000011001000000000000001
10 10000011001000000000000001
11 100000001111100
12 100000001111100
13 100000001111100
14 1000001110110111100000000000001
15 1000001110110111100000000000001
16 1000001110110111100000000000001
17 1000001110110111100000000000001
18 1000001110110111100000000000001
19 1000001110110111100000000000001
20 0001000000000000001
1
2
*****
*****
*****
*****
*****
*****
*****
***** 10
************ 11
************
************
***** *** 14
***** ***
***** ***
***** ***
***** ***
***** ***
20
3W, 12 B, 5W
1000 0000111 1100
If I wanted to suck in the above 20 lines without line numbers, spaces,
carriage returns, line feeds, or anything that is not a zero, one or EOF,
how would I do it?
assuming you mean the twenty lines at the beginning. Would fgets()
followed by
int line_num;
char data[32];
fscanf (line, "%d %32s", &line_num, data);
do the job?

But he would would fgets() followed by fscanf(), wouldn't that just
suck in one line at a time vs all 20 lines at once? Here is what I
mean. BTW, I used sscanf() and not fscanf().

[cdalten@localhost oakland]$ pwd
/home/cdalten/oakland
[cdalten@localhost oakland]$ more bin.txt
1 0001000000000000001
2 0001000000000000001
3 10000011001000000000000001
4 10000011001000000000000001
5 10000011001000000000000001
6 10000011001000000000000001
7 10000011001000000000000001
8 10000011001000000000000001
9 10000011001000000000000001
10 10000011001000000000000001
11 100000001111100000000000001
12 100000001111100000000000001
13 100000001111100000000000001
14 1000001110110111100000000000001
15 1000001110110111100000000000001
16 1000001110110111100000000000001
17 1000001110110111100000000000001
18 1000001110110111100000000000001
19 1000001110110111100000000000001
20 0001000000000000001
[cdalten@localhost oakland]$ more slurp.c
#include <stdio.h>
#include <stdlib.h>

#define PATH "/home/cdalten/oakland/bin.txt"
#define NUMBER 100
#define BIN 1000
#define MAXFMTLEN 2000

int main(void)
{
FILE *fp;
char pattern[MAXFMTLEN];
char lnumber[NUMBER];
char lbin[BIN];
char line[MAXFMTLEN];

/*int line_num;
char data[32];*/

if ((fp = fopen(PATH, "r")) == NULL ) {
fprintf(stderr, "can't open file\n");
exit(1);
}

sprintf(pattern, "%%%ds %%%ds", BIN-1, NUMBER-1);

while ((fgets(line, MAXFMTLEN, fp)) != NULL ) {
sscanf(line, pattern , lnumber, lbin);
/*fscanf (fp, "%d %32s", &lnumber, lbin);*/
printf("%s\n", lbin);
}

fclose(fp);
return 0;

}

[cdalten@localhost oakland]$ gcc -Wall slurp.c -o slurp
[cdalten@localhost oakland]$ ./slurp
0001000000000000001
0001000000000000001
10000011001000000000000001
10000011001000000000000001
10000011001000000000000001
10000011001000000000000001
10000011001000000000000001
10000011001000000000000001
10000011001000000000000001
10000011001000000000000001
100000001111100000000000001
100000001111100000000000001
100000001111100000000000001
1000001110110111100000000000001
1000001110110111100000000000001
1000001110110111100000000000001
1000001110110111100000000000001
1000001110110111100000000000001
1000001110110111100000000000001
0001000000000000001
[cdalten@localhost oakland]$

Yikes! I forgot that using internet slang is a no no here. BTW = by
the way.
Nov 18 '08 #5

P: n/a
George wrote:
On Tue, 18 Nov 2008 00:59:20 -0800 (PST), Nick Keighley wrote:
....
>assuming you mean the twenty lines at the beginning. Would fgets()
followed by

int line_num;
char data[32];

fscanf (line, "%d %32s", &line_num, data);

do the job?

Why fgets before scanf?
Because scanf() treats newline characters the same way as any other
whitespace character. This is usually not the way they should be
handled. As a result, a single incorrectly formatted line can cause all
following lines to be handled incorrectly, causing bugs that can be a
real pain to track down.
Nov 18 '08 #6

P: n/a
On 18 Nov, 09:11, George <geo...@example.invalidwrote:
On Tue, 18 Nov 2008 00:59:20 -0800 (PST), Nick Keighley wrote:
On 18 Nov, 05:44, George <geo...@example.invalidwrote:
1 *0001000000000000001
2 *0001000000000000001
3 *10000011001000000000000001
4 *10000011001000000000000001
5 *10000011001000000000000001
6 *10000011001000000000000001
7 *10000011001000000000000001
8 *10000011001000000000000001
9 *10000011001000000000000001
10 *10000011001000000000000001
11 *100000001111100
12 *100000001111100
13 *100000001111100
14 *1000001110110111100000000000001
15 *1000001110110111100000000000001
16 *1000001110110111100000000000001
17 *1000001110110111100000000000001
18 *1000001110110111100000000000001
19 *1000001110110111100000000000001
20 *0001000000000000001
<snip>
If I wanted to suck in the above 20 lines without line numbers, spaces,
carriage returns, line feeds, or anything that is not a zero, one or EOF,
how would I do it?
assuming you mean the twenty lines at the beginning. Would fgets()
followed by
* *int line_num;
* *char data[32];
* *fscanf (line, "%d %32s", &line_num, data);
do the job?

Why fgets before scanf? *
because it should have read "sscanf()" rather than "fscanf()".
I prefer to separate the reading from the parsing. It makes the error
recovery easier.

The better data set is:

1 *0001000000000000001
2 *0001000000000000001
3 *10000011001000000000000001
4 *10000011001000000000000001
5 *10000011001000000000000001
6 *10000011001000000000000001
7 *10000011001000000000000001
8 *10000011001000000000000001
9 *10000011001000000000000001
10 *10000011001000000000000001
11 *100000001111100000000000001
12 *100000001111100000000000001
13 *100000001111100000000000001
14 *1000001110110111100000000000001
15 *1000001110110111100000000000001
16 *1000001110110111100000000000001
17 *1000001110110111100000000000001
18 *1000001110110111100000000000001
19 *1000001110110111100000000000001
20 *0001000000000000001
something like

int read_binary_data (char data[], FILE *in)
{
char buffer [80];
int line_num;
char junk[2];

if (fgets (buffer, 80, in) == NULL)
return 0; /* i/o error or no more data */

if (strchr(buffer, '\n') == NULL)
return 0; /* line too long */

if (sscanf (buffer, "%d %32s%1s", &line_num, data, junk) != 2)
return 0; /* parse error */

return 1; /* success */
}

that is untested code

--
Nick Keighley

the experience of free will is a gift of ignorance
or a product of incomplete information
Nov 18 '08 #7

P: n/a
Chad <cd*****@gmail.comwrites:
[66 lines deleted]
>But he would would fgets() followed by fscanf(), wouldn't that just
suck in one line at a time vs all 20 lines at once? Here is what I
mean. BTW, I used sscanf() and not fscanf().
[85 lines deleted]
>

Yikes! I forgot that using internet slang is a no no here. BTW = by
the way.
I don't think BTW is a problem; it's common enough that I think almost
everyone understands it. Silly abbreviations like "u" for "you"
are frowned upon.

But you really didn't need to quote the *entire* previous article to
add a one-line comment.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Nov 18 '08 #8

P: n/a
On Tue, 18 Nov 2008 12:26:05 GMT, James Kuyper wrote:
George wrote:
>On Tue, 18 Nov 2008 00:59:20 -0800 (PST), Nick Keighley wrote:
...
>>assuming you mean the twenty lines at the beginning. Would fgets()
followed by

int line_num;
char data[32];

fscanf (line, "%d %32s", &line_num, data);

do the job?

Why fgets before scanf?

Because scanf() treats newline characters the same way as any other
whitespace character. This is usually not the way they should be
handled. As a result, a single incorrectly formatted line can cause all
following lines to be handled incorrectly, causing bugs that can be a
real pain to track down.
How does fgets know to stop?

Presumably, we want to start scanf'ing with '1'. Let me refresh you memory
of the data set. I call it george.txt to reflect my pseudonym.

1 0001000000000000001
2 0001000000000000001
3 10000011001000000000000001
4 10000011001000000000000001
5 10000011001000000000000001
6 10000011001000000000000001
7 10000011001000000000000001
8 10000011001000000000000001
9 10000011001000000000000001
10 10000011001000000000000001
11 100000001111100
12 100000001111100
13 100000001111100
14 1000001110110111100000000000001
15 1000001110110111100000000000001
16 1000001110110111100000000000001
17 1000001110110111100000000000001
18 1000001110110111100000000000001
19 1000001110110111100000000000001
20 0001000000000000001

It's 20 by forty. Given that I premise that the first datum is the line
number, do I still have to fgets?
--
George

Do I think faith will be an important part of being a good president? Yes,
I do.
George W. Bush

Picture of the Day http://apod.nasa.gov/apod/
Nov 20 '08 #9

P: n/a
George <ge****@example.invalidwrites:
On Tue, 18 Nov 2008 12:26:05 GMT, James Kuyper wrote:
>George wrote:
>>On Tue, 18 Nov 2008 00:59:20 -0800 (PST), Nick Keighley wrote:
...
>>>assuming you mean the twenty lines at the beginning. Would fgets()
followed by

int line_num;
char data[32];

fscanf (line, "%d %32s", &line_num, data);

do the job?

Why fgets before scanf?

Because scanf() treats newline characters the same way as any other
whitespace character. This is usually not the way they should be
handled. As a result, a single incorrectly formatted line can cause all
following lines to be handled incorrectly, causing bugs that can be a
real pain to track down.

How does fgets know to stop?
Either the buffer runs out (you tell fgets the size) or the data runs
out.
Presumably, we want to start scanf'ing with '1'. Let me refresh you memory
of the data set. I call it george.txt to reflect my pseudonym.

1 0001000000000000001
2 0001000000000000001
3 10000011001000000000000001
4 10000011001000000000000001
5 10000011001000000000000001
6 10000011001000000000000001
7 10000011001000000000000001
8 10000011001000000000000001
9 10000011001000000000000001
10 10000011001000000000000001
11 100000001111100
12 100000001111100
13 100000001111100
14 1000001110110111100000000000001
15 1000001110110111100000000000001
16 1000001110110111100000000000001
17 1000001110110111100000000000001
18 1000001110110111100000000000001
19 1000001110110111100000000000001
20 0001000000000000001

It's 20 by forty. Given that I premise that the first datum is the line
number, do I still have to fgets?
I would read this using:

int line_no;
char string[41];
while (scanf("%d %40[01]", &line_no, string) == 2)
/* process the data */;

but this is "fragile" -- any upset in the data will throw it off.
Wiser heads than mine advocate reading a line and sscanf'ing it.

As a general bit of advice, it looks like you need to get a C
textbook. I don't think you can lean C by posting questions here.

--
Ben.
Nov 20 '08 #10

P: n/a
George wrote:
On Tue, 18 Nov 2008 12:26:05 GMT, James Kuyper wrote:
>George wrote:
>>On Tue, 18 Nov 2008 00:59:20 -0800 (PST), Nick Keighley wrote:
...
>>>assuming you mean the twenty lines at the beginning. Would fgets()
followed by

int line_num;
char data[32];

fscanf (line, "%d %32s", &line_num, data);

do the job?
Why fgets before scanf?
Key point to keep in mind here: I was thinking of sscanf(), not fscanf()
(or scanf()). The fgets()/sscanf() combo is the best way I know of to
read most text-format files.
>Because scanf() treats newline characters the same way as any other
whitespace character. This is usually not the way they should be
handled. As a result, a single incorrectly formatted line can cause all
following lines to be handled incorrectly, causing bugs that can be a
real pain to track down.

How does fgets know to stop?
It stops at the first newline or when the buffer you've provided it is
full, or at the end of the file, whichever comes first. The key point is
the "newline" - that's what makes this approach more robust when reading
line-oriented files.
Presumably, we want to start scanf'ing with '1'. Let me refresh you memory
of the data set. I call it george.txt to reflect my pseudonym.

1 0001000000000000001
2 0001000000000000001
3 10000011001000000000000001
4 10000011001000000000000001
5 10000011001000000000000001
6 10000011001000000000000001
7 10000011001000000000000001
8 10000011001000000000000001
9 10000011001000000000000001
10 10000011001000000000000001
11 100000001111100
12 100000001111100
13 100000001111100
14 1000001110110111100000000000001
15 1000001110110111100000000000001
16 1000001110110111100000000000001
17 1000001110110111100000000000001
18 1000001110110111100000000000001
19 1000001110110111100000000000001
20 0001000000000000001

It's 20 by forty. Given that I premise that the first datum is the line
number, do I still have to fgets?
If your input file is perfectly formatted, and your program is correctly
written, there's no need. However, I think it's poor design to write
code that fails catastrophically when given incorrect inputs. I believe
in designing programs so they fail gracefully when given bad input. That
means that they fail without undefined behavior, and with an informative
error message, if possible. It's a lot harder to achieve that goal with
fscanf() than it is with fgets()/sscanf().

What happens if the line number is missing from, for example, line 11?
With fscanf(), it will try to interpret 100000001111100 as a decimal
integer, and store it into the line number (with undefined behavior
unless INT_MAX is larger than that value), and then put "12" into the
data buffer. fscanf() will return a value of 2, indicating a successful
read, because it has no way of noticing that anything went wrong. With
fgets()/sscanf(), you can check whether sscanf()==2; if it does not, you
immediately know there's a problem with the line.

Continuing processing despite a problem like that can be pointless, or
mandatory, or anywhere in between those two extremes, depending upon
your application. If you keep using fscanf(), it would attempt to read
100000001111100 as the line number and put "13" into the data buffer; it
will stay out of sync with the actual lines until the end of the file,
or the next incorrectly formatted line, whichever comes first.

With fgets()/sscanf(), fgets() will start cleanly at the next line, so
sscanf() can do exactly what you need it to do; the combination of those
two functions won't stay out of sync with the data, the way fscanf() would.
Nov 20 '08 #11

P: n/a
On Thu, 20 Nov 2008 01:47:02 +0000, Ben Bacarisse wrote:
George <ge****@example.invalidwrites:
>On Tue, 18 Nov 2008 12:26:05 GMT, James Kuyper wrote:
>>George wrote:
On Tue, 18 Nov 2008 00:59:20 -0800 (PST), Nick Keighley wrote:
...
assuming you mean the twenty lines at the beginning. Would fgets()
followed by
>
int line_num;
char data[32];
>
fscanf (line, "%d %32s", &line_num, data);
>
do the job?

Why fgets before scanf?

Because scanf() treats newline characters the same way as any other
whitespace character. This is usually not the way they should be
handled. As a result, a single incorrectly formatted line can cause all
following lines to be handled incorrectly, causing bugs that can be a
real pain to track down.

How does fgets know to stop?

Either the buffer runs out (you tell fgets the size) or the data runs
out.
>Presumably, we want to start scanf'ing with '1'. Let me refresh you memory
of the data set. I call it george.txt to reflect my pseudonym.

1 0001000000000000001
2 0001000000000000001
3 10000011001000000000000001
4 10000011001000000000000001
5 10000011001000000000000001
6 10000011001000000000000001
7 10000011001000000000000001
8 10000011001000000000000001
9 10000011001000000000000001
10 10000011001000000000000001
11 100000001111100
12 100000001111100
13 100000001111100
14 1000001110110111100000000000001
15 1000001110110111100000000000001
16 1000001110110111100000000000001
17 1000001110110111100000000000001
18 1000001110110111100000000000001
19 1000001110110111100000000000001
20 0001000000000000001

It's 20 by forty. Given that I premise that the first datum is the line
number, do I still have to fgets?

I would read this using:

int line_no;
char string[41];
while (scanf("%d %40[01]", &line_no, string) == 2)
/* process the data */;

but this is "fragile" -- any upset in the data will throw it off.
Wiser heads than mine advocate reading a line and sscanf'ing it.

As a general bit of advice, it looks like you need to get a C
textbook. I don't think you can lean C by posting questions here.
I have texts beyond K&R, and the first thing they say is "use of fgets is
deprecated."
If the data set were:
whitespace crlf
whitespace crlf
>1 0001000000000000001
2 0001000000000000001
3 10000011001000000000000001
4 10000011001000000000000001
(sans quoting)

, would the value of fgets before the scanf be realized?
--
George

Freedom itself was attacked this morning by a faceless coward, and freedom
will be defended.
George W. Bush

Picture of the Day http://apod.nasa.gov/apod/
Nov 20 '08 #12

P: n/a
George said:

<snip>
I have texts beyond K&R, and the first thing they say is "use of fgets is
deprecated."
Perhaps you mean gets(). I see no good reason to deprecate fgets().

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Nov 20 '08 #13

P: n/a
On Thu, 20 Nov 2008 02:13:43 GMT, James Kuyper wrote:
George wrote:
>On Tue, 18 Nov 2008 12:26:05 GMT, James Kuyper wrote:
>>George wrote:
On Tue, 18 Nov 2008 00:59:20 -0800 (PST), Nick Keighley wrote:
...
assuming you mean the twenty lines at the beginning. Would fgets()
followed by
>
int line_num;
char data[32];
>
fscanf (line, "%d %32s", &line_num, data);
>
do the job?
Why fgets before scanf?

Key point to keep in mind here: I was thinking of sscanf(), not fscanf()
(or scanf()). The fgets()/sscanf() combo is the best way I know of to
read most text-format files.
>>Because scanf() treats newline characters the same way as any other
whitespace character. This is usually not the way they should be
handled. As a result, a single incorrectly formatted line can cause all
following lines to be handled incorrectly, causing bugs that can be a
real pain to track down.

How does fgets know to stop?

It stops at the first newline or when the buffer you've provided it is
full, or at the end of the file, whichever comes first. The key point is
the "newline" - that's what makes this approach more robust when reading
line-oriented files.
>Presumably, we want to start scanf'ing with '1'. Let me refresh you memory
of the data set. I call it george.txt to reflect my pseudonym.

1 0001000000000000001
2 0001000000000000001
3 10000011001000000000000001
4 10000011001000000000000001
5 10000011001000000000000001
6 10000011001000000000000001
7 10000011001000000000000001
8 10000011001000000000000001
9 10000011001000000000000001
10 10000011001000000000000001
11 100000001111100
12 100000001111100
13 100000001111100
14 1000001110110111100000000000001
15 1000001110110111100000000000001
16 1000001110110111100000000000001
17 1000001110110111100000000000001
18 1000001110110111100000000000001
19 1000001110110111100000000000001
20 0001000000000000001

It's 20 by forty. Given that I premise that the first datum is the line
number, do I still have to fgets?

If your input file is perfectly formatted, and your program is correctly
written, there's no need. However, I think it's poor design to write
code that fails catastrophically when given incorrect inputs. I believe
in designing programs so they fail gracefully when given bad input. That
means that they fail without undefined behavior, and with an informative
error message, if possible. It's a lot harder to achieve that goal with
fscanf() than it is with fgets()/sscanf().

What happens if the line number is missing from, for example, line 11?
With fscanf(), it will try to interpret 100000001111100 as a decimal
integer, and store it into the line number (with undefined behavior
unless INT_MAX is larger than that value), and then put "12" into the
data buffer. fscanf() will return a value of 2, indicating a successful
read, because it has no way of noticing that anything went wrong. With
fgets()/sscanf(), you can check whether sscanf()==2; if it does not, you
immediately know there's a problem with the line.

Continuing processing despite a problem like that can be pointless, or
mandatory, or anywhere in between those two extremes, depending upon
your application. If you keep using fscanf(), it would attempt to read
100000001111100 as the line number and put "13" into the data buffer; it
will stay out of sync with the actual lines until the end of the file,
or the next incorrectly formatted line, whichever comes first.

With fgets()/sscanf(), fgets() will start cleanly at the next line, so
sscanf() can do exactly what you need it to do; the combination of those
two functions won't stay out of sync with the data, the way fscanf() would.
I keep reading this, but I can't work it out in my head right now.

I think I'll go for a walk.

Would you prefer fgets to either Chuck's or Richard's enhancements?
--
George

On September 11 2001, America felt its vulnerability even to threats that
gather on the other side of the Earth. We resolved then, and we are
resolved today, to confront every threat from any source that could bring
sudden terror and suffering to America.
George W. Bush

Picture of the Day http://apod.nasa.gov/apod/
Nov 20 '08 #14

P: n/a
On Thu, 20 Nov 2008 03:18:32 +0000, Richard Heathfield wrote:
George said:

<snip>
>I have texts beyond K&R, and the first thing they say is "use of fgets is
deprecated."

Perhaps you mean gets(). I see no good reason to deprecate fgets().
pg 263

"... use fgets() instead."

Tja. I think it's time for me to karaoke on Lomas avenue and comment
though music how happy I was to have my humptydumped on said avenue. Taxi.
--
George

Iraq is no diversion. It is a place where civilization is taking a decisive
stand against chaos and terror, we must not waver.
George W. Bush

Picture of the Day http://apod.nasa.gov/apod/
Nov 20 '08 #15

P: n/a
George wrote:
Ben Bacarisse wrote:
.... snip ...
>
>As a general bit of advice, it looks like you need to get a C
textbook. I don't think you can lean C by posting questions here.

I have texts beyond K&R, and the first thing they say is "use of
fgets is deprecated."
Then the texts are faulty. Burn them.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
Nov 20 '08 #16

P: n/a
CBFalconer said:
George wrote:
>Ben Bacarisse wrote:
... snip ...
>>
>>As a general bit of advice, it looks like you need to get a C
textbook. I don't think you can lean C by posting questions here.

I have texts beyond K&R, and the first thing they say is "use of
fgets is deprecated."

Then the texts are faulty. Burn them.
Which is more likely? That the textbook is faulty, or that the reader has
mis-read it? I recall reading similar book-burning advice being given in
comp.lang.c, not that long ago, to someone who reported that their book
recommended fflush(stdin). On closer inspection, it turned out that the
book in question did *mention* fflush(stdin) - in a section on undefined
behaviour, and right next to a cite from the Standard explaining that the
behaviour was undefined. Admittedly the author hadn't gone so far as to
say in the sample code:

/* BUG! DON'T DO THIS! BUG! DON'T DO THIS! BUG! DON'T DO THIS! */
/* BUG! DON'T DO THIS! BUG! DON'T DO THIS! BUG! DON'T DO THIS! */
/* BUG! DON'T DO THIS! NO NO NO NO NO! BUG! DON'T DO THIS! */
/* BUG! DON'T DO THIS! */ fflush(stdin); /* BUG! DON'T DO THIS! */
/* BUG! DON'T DO THIS! NO NO NO NO NO! BUG! DON'T DO THIS! */
/* BUG! DON'T DO THIS! BUG! DON'T DO THIS! BUG! DON'T DO THIS! */
/* BUG! DON'T DO THIS! BUG! DON'T DO THIS! BUG! DON'T DO THIS! */

but somehow one gets the feeling that it wouldn't have made any difference
if he had.

"Don't shoot the messenger" only applies when the message is accurate.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Nov 20 '08 #17

P: n/a
On Wed, 19 Nov 2008 21:32:51 -0700, George wrote:
On Thu, 20 Nov 2008 03:18:32 +0000, Richard Heathfield wrote:
>George said:

<snip>
>>I have texts beyond K&R, and the first thing they say is "use of fgets is
deprecated."

Perhaps you mean gets(). I see no good reason to deprecate fgets().

pg 263

"... use fgets() instead."

Tja. I think it's time for me to karaoke on Lomas avenue and comment
though music how happy I was to have my humptydumped on said avenue. Taxi.
[removing --]

George

Bring them on.
George W. Bush

Picture of the Day http://apod.nasa.gov/apod/

According to my calculations, you have 9 minutes to see this beautiful
image. (ABQ -7 Florida -5 you : zero;951 pm local)

Also seen here:

http://antwrp.gsfc.nasa.gov/apod/ap081119.html
Nov 20 '08 #18

P: n/a
George wrote:
On Thu, 20 Nov 2008 02:13:43 GMT, James Kuyper wrote:
....
>If your input file is perfectly formatted, and your program is correctly
written, there's no need. However, I think it's poor design to write
code that fails catastrophically when given incorrect inputs. I believe
in designing programs so they fail gracefully when given bad input. That
means that they fail without undefined behavior, and with an informative
error message, if possible. It's a lot harder to achieve that goal with
fscanf() than it is with fgets()/sscanf().

What happens if the line number is missing from, for example, line 11?
With fscanf(), it will try to interpret 100000001111100 as a decimal
integer, and store it into the line number (with undefined behavior
unless INT_MAX is larger than that value), and then put "12" into the
data buffer. fscanf() will return a value of 2, indicating a successful
read, because it has no way of noticing that anything went wrong. With
fgets()/sscanf(), you can check whether sscanf()==2; if it does not, you
immediately know there's a problem with the line.

Continuing processing despite a problem like that can be pointless, or
mandatory, or anywhere in between those two extremes, depending upon
your application. If you keep using fscanf(), it would attempt to read
100000001111100 as the line number and put "13" into the data buffer; it
will stay out of sync with the actual lines until the end of the file,
or the next incorrectly formatted line, whichever comes first.

With fgets()/sscanf(), fgets() will start cleanly at the next line, so
sscanf() can do exactly what you need it to do; the combination of those
two functions won't stay out of sync with the data, the way fscanf() would.

I keep reading this, but I can't work it out in my head right now.

I think I'll go for a walk.

Would you prefer fgets to either Chuck's or Richard's enhancements?
My news server reports that there are currently 18 messages in this
thread. One was posted by Chuck Falconer, and 2 by Richard Heathfield,
none by anyone else named Chuck or Richard. All three of those messages
are short comments which don't suggest anything I would call an
enhancement. Are you referring to messages which haven't been showing up
on my news server?
Nov 20 '08 #19

P: n/a
James Kuyper said:
George wrote:
<snip>
>Would you prefer fgets to either Chuck's or Richard's enhancements?

My news server reports that there are currently 18 messages in this
thread. One was posted by Chuck Falconer, and 2 by Richard Heathfield,
and all three of them *after* George's message.
none by anyone else named Chuck or Richard. All three of those messages
are short comments which don't suggest anything I would call an
enhancement. Are you referring to messages which haven't been showing up
on my news server?
Despite his use of the word "enhancement", George may be referring to Chuck
Falconer's ggets() function.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Nov 20 '08 #20

P: n/a
Richard Heathfield wrote:
James Kuyper said:
>George wrote:

<snip>
>>Would you prefer fgets to either Chuck's or Richard's enhancements?
My news server reports that there are currently 18 messages in this
thread. One was posted by Chuck Falconer, and 2 by Richard Heathfield,

and all three of them *after* George's message.
>none by anyone else named Chuck or Richard. All three of those messages
are short comments which don't suggest anything I would call an
enhancement. Are you referring to messages which haven't been showing up
on my news server?

Despite his use of the word "enhancement", George may be referring to Chuck
Falconer's ggets() function.
Ah! If so, I will say that I share your frequently expressed negative
opinion of that function, though I don't disapprove of it quite as
passionately as you do.
To George: Google for messages by Richard Heathfield containing ggets().

My biggest problem with ggets() is the lack of support for re-using
buffers that have already been allocated. On those rare occasions when I
want to do anything remotely similar to ggets(), I usually use a
single-line buffer which I realloc() to a larger size whenever a line
comes in which is too big for the current buffer size. I almost never
want to waste time allocating a brand new buffer for every single line
of the input file.
Nov 20 '08 #21

P: n/a
James Kuyper said:
Richard Heathfield wrote:
<snip>
>Despite his use of the word "enhancement", George may be referring to
Chuck Falconer's ggets() function.

Ah! If so, I will say that I share your frequently expressed negative
opinion of that function, though I don't disapprove of it quite as
passionately as you do.
There's nothing wrong with it that can't be fixed. Unfortunately, the owner
doesn't seem to agree that it needs fixing.

<snip>
My biggest problem with ggets() is the lack of support for re-using
buffers that have already been allocated.
Right. It's not exactly difficult to take a char ** and a size_t *.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Nov 20 '08 #22

P: n/a
James Kuyper <ja*********@verizon.netwrites:
My biggest problem with ggets() is the lack of support for re-using
buffers that have already been allocated. On those rare occasions when
I want to do anything remotely similar to ggets(), I usually use a
single-line buffer which I realloc() to a larger size whenever a line
comes in which is too big for the current buffer size. I almost never
want to waste time allocating a brand new buffer for every single line
of the input file.
I'll put in a plug for something like the getline() function from glibc.

ssize_t getline (char **LINEPTR, size_t *N, FILE *STREAM);

*LINEPTR should be a pointer to a buffer of size *N obtained from
malloc. If it is not large enough, it's expanded with realloc, and
*LINEPTR and *N are updated appropriately.

It's very easy to write your own version in standard C, of course.
Unfortunately glibc's code is tightly wound in with the rest of their
stdio library, otherwise it could be swiped and used verbatim in a GPL
program.
Nov 20 '08 #23

P: n/a
James Kuyper wrote:
George wrote:
.... snip ...
>
>Would you prefer fgets to either Chuck's or Richard's enhancements?

My news server reports that there are currently 18 messages in this
thread. One was posted by Chuck Falconer, and 2 by Richard Heathfield,
none by anyone else named Chuck or Richard. All three of those
messages are short comments which don't suggest anything I would call
an enhancement. Are you referring to messages which haven't been
showing up on my news server?
I suspect George is referring to my ggets.c package. This is
available in public domain source form at:

<http://cbfalconer.home.att.net/download/ggets.zip>

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
Nov 20 '08 #24

P: n/a
On Thu, 20 Nov 2008 14:44:08 +0000, Richard Heathfield wrote:
>My biggest problem with ggets() is the lack of support for re-using
buffers that have already been allocated.

Right. It's not exactly difficult to take a char ** and a size_t *.
It's difficult enough for me, who is having quite a time disambiguating all
the terms here. Chuck does have a link to your treatment of this material,
right at the bottom of readme.txt.

pg. 263, unleashed
The gets() function takes as its sole arguments a pointer to char.
Starting at that char, it will probably fill memory with data from stdin
until anewline is encountered, at which point gets90 will probably
null-terminate the string and probably return control to its caller. If,
by some miracle, STDIN contains a newline character within the first N
characters, where N is the supplied buffer, you can take the "probably"
from that sentence--for that one call. If there isn't a newline early
enough, gets() will start to trample over memory that it shouldn't be
touching, with undefined results.
If our way to slurp in these data followed roughly the declarations in
Nick's version:

gets (char data[], FILE *in)
{
char buffer [40];
int line_num;
, you wouldn't need the file *in part, because that's stdin. Are you
saying that:

14 *1000001110110111100000000000001111111111111111111 11111111

would screw it up?

--
George

Leadership to me means duty, honor, country. It means character, and it
means listening from time to time.
George W. Bush

Picture of the Day http://apod.nasa.gov/apod/
Nov 21 '08 #25

P: n/a
On Thu, 20 Nov 2008 15:40:54 -0500, CBFalconer wrote:
James Kuyper wrote:
>George wrote:
... snip ...
>>
>>Would you prefer fgets to either Chuck's or Richard's enhancements?

My news server reports that there are currently 18 messages in this
thread. One was posted by Chuck Falconer, and 2 by Richard Heathfield,
none by anyone else named Chuck or Richard. All three of those
messages are short comments which don't suggest anything I would call
an enhancement. Are you referring to messages which haven't been
showing up on my news server?

I suspect George is referring to my ggets.c package. This is
available in public domain source form at:

<http://cbfalconer.home.att.net/download/ggets.zip>

#include <stdio.h>
#include <stdlib.h>
#include "ggets.h"

#define INITSIZE 112 /* power of 2 minus 16, helps malloc */
#define DELTASIZE (INITSIZE + 16)

enum {OK = 0, NOMEM};

int fggets(char* *ln, FILE *f)

! end abridged source of ggets.c

If this is to replace the use of gets, what need have you of that file
pointer? The only use of f is in getc(f).
--
George

I believe that God has planted in every heart the desire to live in
freedom.
George W. Bush

Picture of the Day http://apod.nasa.gov/apod/
Nov 21 '08 #26

P: n/a
On Thu, 20 Nov 2008 02:13:43 GMT, James Kuyper wrote:
George wrote:
>On Tue, 18 Nov 2008 12:26:05 GMT, James Kuyper wrote:
>>George wrote:
On Tue, 18 Nov 2008 00:59:20 -0800 (PST), Nick Keighley wrote:
...
assuming you mean the twenty lines at the beginning. Would fgets()
followed by
>
int line_num;
char data[32];
>
fscanf (line, "%d %32s", &line_num, data);
>
do the job?
Why fgets before scanf?

Key point to keep in mind here: I was thinking of sscanf(), not fscanf()
(or scanf()). The fgets()/sscanf() combo is the best way I know of to
read most text-format files.
I hadn't even disambiguated these. Am I correct that

scanf
sscanf
fscanf

are the only ones that look like another?
>
>>Because scanf() treats newline characters the same way as any other
whitespace character. This is usually not the way they should be
handled. As a result, a single incorrectly formatted line can cause all
following lines to be handled incorrectly, causing bugs that can be a
real pain to track down.

How does fgets know to stop?

It stops at the first newline or when the buffer you've provided it is
full, or at the end of the file, whichever comes first. The key point is
the "newline" - that's what makes this approach more robust when reading
line-oriented files.

ok
>
>Presumably, we want to start scanf'ing with '1'. Let me refresh you memory
of the data set. I call it george.txt to reflect my pseudonym.

1 0001000000000000001
2 0001000000000000001
3 10000011001000000000000001
4 10000011001000000000000001
5 10000011001000000000000001
6 10000011001000000000000001
7 10000011001000000000000001
8 10000011001000000000000001
9 10000011001000000000000001
10 10000011001000000000000001
11 100000001111100
12 100000001111100
13 100000001111100
14 1000001110110111100000000000001
15 1000001110110111100000000000001
16 1000001110110111100000000000001
17 1000001110110111100000000000001
18 1000001110110111100000000000001
19 1000001110110111100000000000001
20 0001000000000000001

It's 20 by forty. Given that I premise that the first datum is the line
number, do I still have to fgets?

If your input file is perfectly formatted, and your program is correctly
written, there's no need. However, I think it's poor design to write
code that fails catastrophically when given incorrect inputs. I believe
in designing programs so they fail gracefully when given bad input. That
means that they fail without undefined behavior, and with an informative
error message, if possible. It's a lot harder to achieve that goal with
fscanf() than it is with fgets()/sscanf().

What happens if the line number is missing from, for example, line 11?
With fscanf(), it will try to interpret 100000001111100 as a decimal
integer, and store it into the line number (with undefined behavior
unless INT_MAX is larger than that value), and then put "12" into the
data buffer. fscanf() will return a value of 2, indicating a successful
read, because it has no way of noticing that anything went wrong. With
fgets()/sscanf(), you can check whether sscanf()==2; if it does not, you
immediately know there's a problem with the line.

Continuing processing despite a problem like that can be pointless, or
mandatory, or anywhere in between those two extremes, depending upon
your application. If you keep using fscanf(), it would attempt to read
100000001111100 as the line number and put "13" into the data buffer; it
will stay out of sync with the actual lines until the end of the file,
or the next incorrectly formatted line, whichever comes first.

With fgets()/sscanf(), fgets() will start cleanly at the next line, so
sscanf() can do exactly what you need it to do; the combination of those
two functions won't stay out of sync with the data, the way fscanf() would.
#include <stdio.h>
#include <stdlib.h>

#define PATH "george.txt"
#define NUMBER 100
#define BIN 1000
#define MAXFMTLEN 2000

int main(void)
{
FILE *fp;
char pattern[MAXFMTLEN];
char lnumber[NUMBER];
char lbin[BIN];
char line[MAXFMTLEN];

if ((fp = fopen(PATH, "r")) == NULL ) {
fprintf(stderr, "can't open file\n");
exit(1);
}

sprintf(pattern, "%%%ds %%%ds", BIN-1, NUMBER-1);

while ((fgets(line, MAXFMTLEN, fp)) != NULL ) {
sscanf(line, pattern , lnumber, lbin);
/*fscanf (fp, "%d %32s", &lnumber, lbin);*/
printf("%s\n", lbin);
}
Q1) Does the while control satisfy your critism above?

Q2) Why doesn't the sprintf have to *follow* the while?

whitespace crlf
whitespace crlf
1 0001000000000000001
2 0001000000000000001
3 10000011001000000000000001
4 10000011001000000000000001
--
George

If you're sick and tired of the politics of cynicism and polls and
principles, come and join this campaign.
George W. Bush

Picture of the Day http://apod.nasa.gov/apod/
Nov 21 '08 #27

P: n/a
On Tue, 18 Nov 2008 09:15:43 -0800, Keith Thompson wrote:
Chad <cd*****@gmail.comwrites:
[66 lines deleted]
>>But he would would fgets() followed by fscanf(), wouldn't that just
suck in one line at a time vs all 20 lines at once? Here is what I
mean. BTW, I used sscanf() and not fscanf().
[85 lines deleted]
>>

Yikes! I forgot that using internet slang is a no no here. BTW = by
the way.

I don't think BTW is a problem; it's common enough that I think almost
everyone understands it. Silly abbreviations like "u" for "you"
are frowned upon.

But you really didn't need to quote the *entire* previous article to
add a one-line comment.
Chad's fine.

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

#define PATH "george.txt"
#define NUMBER 100
#define BIN 1000
#define MAXFMTLEN 2000

int main(void)
{
FILE *fp;
char pattern[MAXFMTLEN];
char lnumber[NUMBER];
char lbin[BIN];
char line[MAXFMTLEN];

/*int line_num;
char data[32];*/
// was this an earlier version?

if ((fp = fopen(PATH, "r")) == NULL ) {
fprintf(stderr, "can't open file\n");
exit(1);
}

sprintf(pattern, "%%%ds %%%ds", BIN-1, NUMBER-1);

while ((fgets(line, MAXFMTLEN, fp)) != NULL ) {
sscanf(line, pattern , lnumber, lbin);
/*fscanf (fp, "%d %32s", &lnumber, lbin);*/
printf("%s\n", lbin);
}

fclose(fp);
return 0;
}

// gcc -o x.exe chad1.c

I see no useful distinction between

#define NUMBER 100
#define BIN 1000
, if there were to be meaningful line numbers. The next part of the
process is that I strip away anything that isn't a one or a zero in a range
of columns, so it's no big deal.

I'm a little sketchy about this line,
sscanf(line, pattern , lnumber, lbin);
in particular the meaning of pattern, when there's already a line, an
lnumber and an lbin.

BTW, everyone has equal editorial priveleges. As OP, I'm just more
equal.:-)
--
George

Saddam Hussein is a homicidal dictator who is addicted to weapons of mass
destruction.
George W. Bush

Picture of the Day http://apod.nasa.gov/apod/
Nov 21 '08 #28

P: n/a
On Thu, 20 Nov 2008 10:45:13 -0800, Nate Eldredge wrote:
James Kuyper <ja*********@verizon.netwrites:
>My biggest problem with ggets() is the lack of support for re-using
buffers that have already been allocated. On those rare occasions when
I want to do anything remotely similar to ggets(), I usually use a
single-line buffer which I realloc() to a larger size whenever a line
comes in which is too big for the current buffer size. I almost never
want to waste time allocating a brand new buffer for every single line
of the input file.

I'll put in a plug for something like the getline() function from glibc.

ssize_t getline (char **LINEPTR, size_t *N, FILE *STREAM);

*LINEPTR should be a pointer to a buffer of size *N obtained from
malloc. If it is not large enough, it's expanded with realloc, and
*LINEPTR and *N are updated appropriately.

It's very easy to write your own version in standard C, of course.
Unfortunately glibc's code is tightly wound in with the rest of their
stdio library, otherwise it could be swiped and used verbatim in a GPL
program.
Are you on gcc's mailing list? How would you do that without having 20
emails a day in a mailbox that gets 2 personal and important emails a week?

gmane?
--
George

Now, there are some who would like to rewrite history - revisionist
historians is what I like to call them.
George W. Bush

Picture of the Day http://apod.nasa.gov/apod/
Nov 22 '08 #29

P: n/a
George <ge****@example.invalidwrites:
On Thu, 20 Nov 2008 14:44:08 +0000, Richard Heathfield wrote:
>>My biggest problem with ggets() is the lack of support for re-using
buffers that have already been allocated.

Right. It's not exactly difficult to take a char ** and a size_t *.

It's difficult enough for me, who is having quite a time disambiguating all
the terms here. Chuck does have a link to your treatment of this material,
right at the bottom of readme.txt.

pg. 263, unleashed
The gets() function takes as its sole arguments a pointer to char.
Starting at that char, it will probably fill memory with data from stdin
until anewline is encountered, at which point gets90 will probably
null-terminate the string and probably return control to its caller. If,
by some miracle, STDIN contains a newline character within the first N
characters, where N is the supplied buffer, you can take the "probably"
from that sentence--for that one call. If there isn't a newline early
enough, gets() will start to trample over memory that it shouldn't be
touching, with undefined results.
Is that a 99.8% verbatim quote, because it looks horrifically mangled?
(I subtract .2%, as I presume 90 was really () sans shift key, and your
whitespace is a bit dodgy.)

Phil
--
I tried the Vista speech recognition by running the tutorial. I was
amazed, it was awesome, recognised every word I said. Then I said the
wrong word ... and it typed the right one. It was actually just
detecting a sound and printing the expected word! -- pbhj on /.
Nov 22 '08 #30

P: n/a
George wrote:
CBFalconer wrote:
>James Kuyper wrote:
>>George wrote:
... snip ...
>>>
Would you prefer fgets to either Chuck's or Richard's enhancements?

My news server reports that there are currently 18 messages in this
thread. One was posted by Chuck Falconer, and 2 by Richard Heathfield,
none by anyone else named Chuck or Richard. All three of those
messages are short comments which don't suggest anything I would call
an enhancement. Are you referring to messages which haven't been
showing up on my news server?

I suspect George is referring to my ggets.c package. This is
available in public domain source form at:

<http://cbfalconer.home.att.net/download/ggets.zip>

#include <stdio.h>
#include <stdlib.h>
#include "ggets.h"

#define INITSIZE 112 /* power of 2 minus 16, helps malloc */
#define DELTASIZE (INITSIZE + 16)

enum {OK = 0, NOMEM};

int fggets(char* *ln, FILE *f)

! end abridged source of ggets.c
That is YOUR abridgement, not mine.
>
If this is to replace the use of gets, what need have you of
that file pointer? The only use of f is in getc(f).
Because fggets can read text lines from any file. ggets is a
macro, that supplies stdin as the source file id.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
Nov 22 '08 #31

This discussion thread is closed

Replies have been disabled for this discussion.