0

Is there a way to make this error checking any better? Or is there something I am forgetting? I am expecting an integer then string. I added the suggestions to the code.

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

int main(void) {
    // your code goes here
    char line[150] = {0};
    int sscanf_counter = 0;
    int num = 0;
    char string[150] = {0};
    char dummy; 

    while(fgets(line, sizeof line, stdin))
    {
        printf("line is %s\n", line);
        sscanf_counter = sscanf(line, "%d %s %c", &num, string, &dummy);
        printf ("sscanf_counter: %d\n", sscanf_counter);
        if (sscanf_counter == 2 && isalpha(string[0])) 
        {
            printf ("Good value: %d\n", num);
            printf ("string: <%s>\n", string);
        }
        else 
        {
            printf ("BAD VALUE: %d \n", num);
            printf ("string: <%s>\n", string);
        }
        memset(line, 0, sizeof line);
    }

    printf("Does this print? \n");

    return 0;
}

I didn't want 222 to be converted to a string so I added a simple isalpha() check to my code. I want an actual number for my first value and actual alphabet characters not numbers converted to a string for the second value.

Output with small tweak:

aaa aaa
line is aaa aaa

sscanf_counter: 0
BAD VALUE: 0
string: <>
111 222
line is 111 222

sscanf_counter: 2
BAD VALUE: 111
string: <222>
111 aaa
line is 111 aaa

sscanf_counter: 2
Good value: 111
string: <aaa>
6
  • For even better feedback, post the true input used, output seen and output expected. Commented Nov 18, 2017 at 2:05
  • @chux I updated my code. I added the small tweak of isalpha() check to my code. Commented Nov 18, 2017 at 3:06
  • 1
    noobprogrammer1987 isalpha(string[0]) is not defined for most negative values of string[0]. Highly portable code uses isalpha((unsigned char) string[0]) Commented Nov 18, 2017 at 3:09
  • @chux it is not even "highly portable", many debug CRTs on the most used signed-char platforms ;) will outright assert for negative values. Commented Nov 18, 2017 at 7:28
  • @AnttiHaapala can you elaborate on what your talking about? Commented Nov 24, 2017 at 7:48

1 Answer 1

1

Is there a way to make this error checking any better?

"%d" is not specified on overflow. Stronger error checking can be provided with strtol().

"%d %s" does not detect extraneous extra input.

To deal with extra input and still use sscanf(), see below. If sscanf_counter == 3, extra non-white-space input detected.

char dummy;
sscanf_counter = sscanf(line, "%d %s %c", &num, string, &dummy);

The test if (sscanf_counter == ...) should happen before using the variables.

  printf ("sscanf_counter: %d\n", sscanf_counter);
  if (sscanf_counter >= 1) printf ("num: %d\n", num);
  if (sscanf_counter >= 2) printf ("string: %s\n", string);

Tip: when printing a string, consider printable sententials to help detect leading/trailing white-space issues. (Even though these are not expected with "%s".)

// printf ("string: %s\n", string);
printf ("string: <%s>\n", string);

OT: Rather than code magic numbers, use code that adapts

// memset(line, 0, 150);
memset(line, 0, sizeof line);

// while(fgets(line, 150, stdin) != NULL)
while (fgets(line, sizeof line, stdin))
Sign up to request clarification or add additional context in comments.

6 Comments

thank you. I assume adding the dummy to end of the sscanf is just for telling me if there is extra input? Does it do anything else? What do you mean by printable sententials? Thank you for the sizeof reminder. Are the parenthesis sizeof optional? I was surprised the first time I used sizeof without parenthesis and had no issues.
Does it not need the != NULL at the end of the while loop?
@noobprogrammer1987 while (fgets(line, sizeof line, stdin)) and while (fgets(line, sizeof line, stdin) != NULL) function the same, Code per your group's coding style.
@noobprogrammer1987 sizeof object codes the same as sizeof(object). With type, must use sizeof(type).
@noobprogrammer1987 Yes, dummy is there to detect extra input.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.