Home > other >  Read lines from an input file of varying line sizes
Read lines from an input file of varying line sizes

Time:11-23

Currently, I am using getline to read lines from a file and I can access individual characters the following way from stdin:

char buffer[1024];
while((lineSize = getline(&line, &len, stdin)) != -1) {
            if (line[0] != 84) {
                // ...
                continue; // continue to next line in file
            }
            if (line[0] == 84){ // (the 'T' character)
                printf("TEST: Line Value: %s\n", line);
                buffer[0] = line[1]; // this is a single digit number in char form
                buffer[1] = '\0';
                // send buffer somewhere
                send(clientSocket, buffer, strlen(buffer), 0);
                // ...
}

A sample file is as follows:

T3
T9
S0
S4
T55
T6

However, as you can see, I run into issues when a number > 9 is given such as the T55 line here. I can only grab the first digit with this method. Therefore, I may have to completely redo the way I read a file. Is there a better and simple way I can read through an input file and check the first character and make the remaining character(s) into an int until the end of a line? (Max the integer can be is 100 btw)

CodePudding user response:

Continuing from my comments, you can use fgets() to read line and then use sscanf() with the format string of " %c%d%n" to extract the first character and converting the next set of digits to an int and finally obtaining to total number of characters consumed by sscanf() in that conversion using the "%n" specifier. You validate that both the character and integer conversion took place and that the first non-whitespace character read was 'T'. You can then use mychar and myint as desired and use mylen as the length to use with send.

(note: you can scan forward in line to determine if any whitespace was included at the beginning and ignore than in your call to send() -- that is left to you)

Putting it altogether, you can so something like:

  char line[1024],
       mychar = 0;
  int myint = 0,
      mylen;
  
  /* read using fgets */
  while (fgets (line, sizeof line, stdin)) {
    /* parse with sscanf, validate both conversions and 'T' as 1st char,
     * use "%n" to get number of chars through int conversion
     */
    if (sscanf (line, " %c%d%n", &mychar, &myint, &mylen) != 2 || 
                mychar != 'T') {
      fputs ("error: invalid format.\n", stderr);
      continue;
    }
    
    send (clientSocket, line, mylen, 0);    /* send mylen chars */
  }

To be more specific, I will need to see your Minimal Complete Reproducible Example to ensure there is nothing outside what you have posted that will impact the code above.


Adding Example

Adding a short example to show the result of parsing under expected and unexpected input with the above, and adding the scanning forward to remove leading whitespace in the line, a short program that reads input from stdin and writes to stdout, outputting the lines matching 'T'(int), you could do:

#include <stdio.h>
#include <unistd.h>
#include <ctype.h>

int main (void) {

  char line[1024],
       mychar = 0,
       nl = '\n';
  int myint = 0,
      mylen;
  
  /* read using fgets */
  while (fgets (line, sizeof line, stdin)) {
    char *p = line;
    /* parse with sscanf, validate both conversions and 'T' as 1st char,
     * use "%n" to get number of chars through int conversion
     */
    if (sscanf (line, " %c%d%n", &mychar, &myint, &mylen) != 2 || 
        mychar != 'T') {
      fprintf (stderr, "error: invalid format: %s", line);
      continue;
    }
    
    while (isspace (*p)) {    /* reamove leading whitespace */
      p  = 1;
      mylen -= 1;
    }
    
    // send (clientSocket, p, mylen, 0);    /* send mylen chars */
    write (STDOUT_FILENO, p, mylen);
    write (STDOUT_FILENO, &nl, 1);
  }
}

(note: write (STDOUT_FILENO, &nl, 1); is simply included above to output a newline after each output -- it would not be part of what you send() over your socket -- unless the receiving program is using the '\n' as the line termination character)

Example Input File:

$ cat dat/charint.txt
T4
T44
T444
 TT
 T3 and more gibberish
P55

(note: leading whitespace and trailing characters included in last two lines beginning with 'T', including the invalid line format " TT")

Example Use/Output

$ ./bin/charandintsend < dat/charint.txt
T4
T44
T444
error: invalid format:  TT
T3
error: invalid format: P55

Let me know if you have questions, or if I misunderstood some aspect of your question.

  • Related