Hi,
The programs below try to read a file and print its contents to a block of 72 chars wide. The point of the programs is for me to learn not to cram everything into main(). What I'd like it to do is the following in pseudo code:
Code:
/*
func1()
open text file
func2()
make '\0' terminated line
return pointer of line to main
main()
func1()
loop func2 until EOF
*/
The first kludge I came up with is this:
Code:
// readfile1.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
static FILE *open_file(char *file, char *mode)
{
FILE *fp = fopen(file, mode);
if (fp == NULL) {
perror("fopen: ");
exit(EXIT_FAILURE);
}
return fp;
}
char *read_line(int line_length, FILE *txt)
{
int i, character;
char *line;
line = (char *)malloc(line_length);
FILE *text;
for (i = 0; i < (line_length - 1); i++) {
if ((character = fgetc(text)) == EOF) {
perror("fgetc: ");
exit(EXIT_SUCCESS);
}
line[i] = character;
}
line[line_length - 1] = '\0';
return(line);
}
int main(int argc, char *argv[])
{
int length = 73;
FILE *open;
open = open_file(argv[1], "r");
int i;
// This test loop is a place holder for a loop_until_EOF.
// It segfaults at i = 1.
for (i = 0; i < 4; i++) printf("%s\n", read_line(length, open));
return(EXIT_SUCCESS);
}
Code:
heras@vhbh:~/code/c$ ./read1 ~/code/text
Open text file for reading. The stream is positioned at the beginning
Segmentation fault (core dumped)
The malloc in the readline() funtion is probably a bad idea because it would require a seperate line = (char *)malloc(line_length); buffer for each line that is read from the source file. And to free() them (I'm not at that point yet) might be cumbersome. Is any of this true?
Then I tried to move the malloc to main() and pass line_pointer to read_line() hoping read_line() might write to it. This is not working at all:
Code:
//readfile2.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
static FILE *open_file(char *, char *);
char *read_line(int, FILE *, char *);
int main(int argc, char *argv[])
{
FILE *open;
open = open_file(argv[1], "r");
int i;
int length = 73;
char *line_pointer;
line_pointer = (char *)malloc(length);
for (i = 0; i < 4; i++) {
printf("%s\n", read_line(length, open, line_pointer));
}
return(EXIT_SUCCESS);
}
static FILE *open_file(char *file, char *mode)
{
FILE *fp = fopen(file, mode);
if (fp == NULL) {
perror("fopen");
exit(EXIT_FAILURE);
}
return(fp);
}
char *read_line(int line_length, FILE *txt, char *lp)
{
int i;
char *character = lp;
FILE *text;
for (i = 0; i < (line_length - 1); i++) {
*character++ = fgetc(text);
}
return(lp);
}
Code:
heras@vhbh:~/code/c$ ./read2 ~/code/text
Segmentation fault (core dumped)
Code:
(gdb) b main
Breakpoint 1 at 0x80484a5: file readfile2.c, line 12.
(gdb) r ~/code/text
Starting program: /home/heras/code/c/read2 ~/code/text
Breakpoint 1, main (argc=2, argv=0xbfcea004) at readfile2.c:12
12 open = open_file(argv[1], "r");
(gdb) n
15 int length = 73;
(gdb)
17 line_pointer = (char *)malloc(length);
(gdb)
18 for (i = 0; i < 4; i++) {
(gdb)
19 printf("%s\n", read_line(length, open, line_pointer));
(gdb)
Program received signal SIGSEGV, Segmentation fault.
0xb7edb46d in getc () from /lib/tls/i686/cmov/libc.so.6
(gdb)
Single stepping until exit from function getc,
which has no line number information.
Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.
I have no clear question, by now I don't know what I'm doing anymore. Any guidance or hints on how to construct such a program would be greatly appreciated.
Two more minor / unimportant issues:
- printing a line is off by 2. It prints 70 characters but I don't see why
- if I get this to work at all, to reuse it in a socket/network program with as little modification as possible
Thanks,
heras