0

I'm trying to read three 3 values from a text file (in.txt) that are from the first line. How am I able to implement this in C?

The first line of the text file has 3 numbers (N, S, D). And they represent the sequence of input words in the file. So for example my in.txt file would be:

8 3 5
mary
tom
jane
joe
dave
judy
fred
bill
jane
jones
judy
mary
judy
fred
joe
dave

So the first 8 will correspond to N, following 3 to S, and the last 5 to D. The purpose for this is for me to add the first 8 into a Binary Search Tree, then following 3 to Search in the BST, and the last 5 to delete from the BST.

But for this all I want to know is how I'm able to read them from a file in order to start my BST.

I haven't gotten very far I've only been able to open the file but had to delete other codes due to it not working at all. So this is all I have right now.

int main()
{
    FILE *inFile, *outFile; 
    int n, s, d; 

    inFile = fopen("in.txt", "r");

    while(!feof (inFile))
    {
        fscanf(inFile, "%d %d %d", &n, &s, &d);
    }
    fclose(inFile);
}

This is my first post here on Stackoverflow, any help is greatly appreciated!

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
Aly D
  • 1
  • 1

2 Answers2

1

To begin with, you will want to review Why is while ( !feof (file) ) always wrong?

When reading lines of data from a file, use a line-oriented input function such as fgets() or POSIX getline() to read an entire line into a buffer -- then parse the needed values from the buffer. This provides two primary benefits:

  1. you can independently validate:

    a. the read of data from the file; and

    b. parsing of the values from the line.

  2. what remains in your input buffer does not depend on the scanf format-specifier used. (an entire line is always consumed, so you are always ready to read from the beginning of the next line for your next input)

Any time you are reading from a file, simply provide a buffer of sufficient size when using fgets (don't skimp on buffer size!). POSIX getline will automatically allocate whatever space is required. Then use sscanf to parse any information needed from the line (or strtok or strsep or any of the other functions you like to locate a specific point within the buffer).

If you are not parsing information and need the whole line, simply trim the '\n' from the end of the buffer by overwriting it with the nul-character. strcspn provides a simple method, or use strlen to get the length then overwrite the last character.

In your case you simply need to handle the first line differently from the remaining lines -- so keep a line-counter initialized to zero at the beginning. If your line counter is zero, then parse 3-integer values from the line, otherwise do whatever you need with the subsequent lines (below they are simply output with along with the line number)

Putting it altogether, you could do something similar to:

#include <stdio.h>
#include <string.h>

#define MAXC 1024   /* don't skimp on buffer size */

int main (int argc, char **argv) {

    char buf[MAXC];     /* buffer to hold each line */
    int n, s, d;        /* your int variables */
    size_t ndx = 0;     /* line counter */
    /* use filename provided as 1st argument (stdin by default) */
    FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;

    if (!fp) {  /* validate file open for reading */
        perror ("file open failed");
        return 1;
    }

    while (fgets (buf, MAXC, fp)) {     /* read each line into buf */
        if (!ndx) {     /* if 1st line, parse into n, s, d */
            if (sscanf (buf, "%d %d %d", &n, &s, &d) == 3)
                printf ("line[%2zu] - n: %d  s: %d  d: %d\n", 
                        ndx + 1, n, s, d);
            else {      /* if parse fails - handle error */
                fputs ("error: invalid format - line 1.\n", stderr);
                return 1;
            }
        }
        else {  /* for all subsequent lines */
            buf[strcspn(buf, "\r\n")] = 0;      /* trim '\n' from buf */
            printf ("line[%2zu] : %s\n", ndx + 1, buf);
        }
        ndx++;  /* increment line counter */
    }
    if (fp != stdin) fclose (fp);   /* close file if not stdin */

    return 0;
}

Example Use/Output

Using your input file, you would get the following:

$ ./bin/rdline1_3int dat/line1_3int.txt
line[ 1] - n: 8  s: 3  d: 5
line[ 2] : mary
line[ 3] : tom
line[ 4] : jane
line[ 5] : joe
line[ 6] : dave
line[ 7] : judy
line[ 8] : fred
line[ 9] : bill
line[10] : jane
line[11] : jones
line[12] : judy
line[13] : mary
line[14] : judy
line[15] : fred
line[16] : joe
line[17] : dave
David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
0

I would do a thing like this:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>


void main()
{
int fd, N, S, D;
char buff[1];
fd = open("in.txt", O_RDONLY);


//reading N
if(read(fd, buff, 1) == -1){
    perror("Unable to read N");
    exit(0);
}
//converting N to int value
//EDIT
N = atoi(buff);

//skipping the file descriptor to avoid reading the space
lseek(fd, 1, SEEK_CUR);
//reading S
if(read(fd, buff, 1) == -1){
    perror("Unable to read S");
    exit(0);
}
//converting S to int value
//EDIT
S = atoi(buff);

//skipping the file descriptor to avoid reading the space
lseek(fd, 1, SEEK_CUR);
//reading D
if(read(fd, buff, 1) == -1){
    perror("Unable to read N");
    exit(0);
}
//converting D to int value
//EDIT
D = atoi(buff);;

close(fd);
//here your values are initialized
}

I didn't test this code, so it may not work, let me know if its working :)

Ezio
  • 13
  • 3
  • Thank you for contributing to help! Unfortunately, when I ran the code it doesn't work. It didn't print anything not even the Error message. So I assumed it did open the file. However, is there anyway it could be done without the additional libraries? Such as sticking with stdio.h/stdlib.h. Since my assignment doesn't require those additional ones. Thank you again! – Aly D Apr 15 '19 at 19:18
  • Does it run ? It is assuming to print nothing, the sprintf function is used to convert the char value read from the file into a int value. By the way i forgot to include the string.h library, try to add a printf function that prints N S and D values and see and let me know what happens. About the libraries you can open the file the way you did, but i raccomand use the lseek and read funct, in order to let you decide where and what (in bytes) to read. – Ezio Apr 15 '19 at 19:41
  • Yes the program runs, and I just added the string.h library and tried to add a printf function that prints N, S, and D. Yet it still does not appear in the output window. – Aly D Apr 15 '19 at 20:04
  • I edited the code, replace the *sprintf* functions with *atoi* ones. With the sprintf i was converting string value into (again) string. I was looking for atoi function. I'm sorry for the misunderstanding, i hope that now the code is working :) – Ezio Apr 16 '19 at 07:32