David Edgar David Edgar - 12 days ago 4
C Question

Distinguish between new line and errors when using sscanf

I'm having a harsh time achieving this. I read a string of integer, extract them from that chain and put them in an array. I wanted to try something new because a used to read character by character with

getChar
in the past, but now I find
sscanf
which handle the job.

From Doc (sscanf) :
On success, the function returns the number of items in the argument list successfully filled. This count can match the expected number of items or be less (even zero) in the case of a matching failure.
In the case of an input failure before any data could be successfully interpreted, EOF is returned.

line :
char line[] = "100 185 20 11 1000"; // number of int is unknown, it can differ


Problem: How to make diffrence between end of line and a whatever error

Eg:
char line[] = "100 185 abc(not int) 11 1000";


Code :

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

char line[] = "100 185 20 11 1000";
int arrOfInt[10];
char *data = line;
int track, number, index = 0;

while ((sscanf(data, " %d%n", &number, &track)) == 1)
{
arrOfInt[index] = number;
data += track;
index++;
}
return 0;
}

Answer

@BLUEPIXY mentioned the correct answer. Just formalizing it here.

If the return value of scanf is EOF that means an EOF is seen. If it is 0 that means some other error has occurred(eg. the input does not match the format specified)

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv) {

    char line[] = "100 185 20 11 1000 sdf 342";    
    int  arrOfInt[10];
    char *data = line;
    int  track, status = 0, number, index = 0;

    // read until an EOF is found
    while ((status = sscanf(data, " %d%n", &number, &track)) != EOF)
    {
        // store only if status is non-zero i.e. sscanf has read according to the format specified
        if(status != 0){
            arrOfInt[index] = number;
            index++;
        }
        data += track;
    }
    // print the array back to check if we read correctly
    int i;
    for(i=0;i<index;i++)
    printf("%d ", arrOfInt[i]);
    return 0;
}

The output of this code is:

100 185 20 11 1000 342 

Also, you approach of checking whether the return value of sscanf matches the number of arguments specified is also correct, i.e. the following code will also work.

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv) {

    char line[] = "100 185 20 11 1000 sdf 342";    
    int  arrOfInt[10];
    char *data = line;
    int  track, status = 0, number, index = 0;

    // read until an EOF is found
    while ((status = sscanf(data, " %d%n", &number, &track)) != EOF)
    {
        // store only if status is one i.e. sscanf has read the number of specified arguments
        if(status == 1){
            arrOfInt[index] = number;
            index++;
        }
        data += track;
    }
    // print the array back to check if we read correctly
    int i;
    for(i=0;i<index;i++)
    printf("%d ", arrOfInt[i]);
    return 0;
}
Comments