C: modify file to read from external file

Viewed 143

I'm working through The C Programming Language - 2nd Edition, trying to reason through the examples. I'm brand-new to C.

Much of the example code from the first chapter relies on getchar() to receive input. For instance, the following code, which returns the longest line of a block of text:

#include <stdio.h>

#define     MAXLINE 1000

int max;
char line[MAXLINE];
char longest[MAXLINE];

int getline(void);
void copy(void);

int main()
{  
    int len;
    extern int max;
    extern char longest[];

    max = 0;
    while ((len = getline()) > 0)
        if (len > max) {
            max = len;
            copy();
        }
    if (max > 0)
        printf("%s", longest);
    return 0;        
}

int getline(void) {
    int c, i;
    extern char line[];

    for (i = 0; i < MAXLINE-1 && (c=getchar()) != EOF && c != '\n'; ++i)
        line[i] = c;
    
    if (c == '\n') {
        line[i] = c;
        ++i;
    }
    line[i] = '\0';
    return i;
}

void copy(void) {
    int i;
    extern char line[], longest[];

    i=0;
    while ((longest[i] = line[i]) != '\0')
        ++i
}

Probably a simple answer, but what do I have to do to provide an external text file as input to this program?

EDIT: I've tried the following but am getting compilation errors:

#include <stdio.h>

#define     MAXLINE 1000

int max;
char line[MAXLINE];
char longest[MAXLINE];
FILE *fp; 

int getline(void);
void copy(void);

int main()
{  
    int len;
    extern int max;
    extern char longest[];
    fp = fopen("./hello.txt", "r");

    max = 0;
    while ((len = getline()) > 0)
        if (len > max) {
            max = len;
            copy();
        }
    if (max > 0)
        printf("%s", longest);
    
    fclose(fp);
    return 0;        
}

int getline(void) {
    int c, i;
    extern char line[];
    extern FILE *fp;

    for (i = 0; i < MAXLINE-1 && (c=fgetc(fp)) != EOF && c != '\n'; ++i)
        line[i] = c;
    
    if (c == '\n') {
        line[i] = c;
        ++i;
    }
    line[i] = '\0';
    return i;
}

void copy(void) {
    int i;
    extern char line[], longest[];

    i=0;
    while ((longest[i] = line[i]) != '\0')
        ++i;
}
1 Answers

fopen("./hello.txt", "r"); opens and buffers a file named "./hello.txt" for reading.

Unless your file really is named with the ./ (aren't /in filenames illegal in UNIX and the like ?), you should remove the ./ from the string literal you pass as filename.


Compilation errors in your posted 'original' code are :

  1. getline() can't really be re-defined if you include stdio.h on some platforms , over here MacOS, since it is defined/declared there as :

ssize_t getline(char ** __restrict __linep, size_t * __restrict __linecapp, FILE * __restrict __stream)

Basically, rename getline() to something trivially different, say like getln().

Alternatively, force the compiler, here Clang, to operate strictly within a standard , say C99, by adding a -stdC99 option to the arguments during compilation.

This seems non-standard at least in C, maybe not in C++, but this is how it is on MacOS's stdio.h.

To be precise, version 10.14.6 , line 359 of /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/stdio.h

  1. A missing ; after ++i @ line 50 col 12.

Further, as with most I/O in languages like C , your program is missing some fundamental error checking - very importantly , for example, checking fp == NULL in case fopen() fails, which will happen for example if hello.txt does not exist, which would be bad since fclose(NULL) is a seg fault.

You will understand this as you learn (stream-level) File I/O in C, perhaps subsequently.

If you are not at the level of learning stdio.h -based File I/O yet, why not just use the more convenient feature of redirecting input from the console ? Just do hello.txt > ./yourprogram or hello.txt | ./yourprogram when running the original textbook code from the terminal.

Works on UNIX-based systems and even Windows and DOS, and is often used in such cases where the pains of implementing file I/O directly are not worth it.

Related