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.