1

Going through some entry level C programming and having trouble with this seemingly very simple logical operator. The first if statement is skipped if you enter last name Paul. Also trying to understand buffer size when using scanf_s.

int main(){

    char name[25];

    printf("what is your last name? ");
    printf("(Please capitalize the first letter!)\n");
    scanf_s(" %s", name, 2); 

    if ((name[0] >= 'P') && (name[0] <= 'S'))

    {
        printf("You must go to room 232 for your tickets\n ");
    }
    else
    {
        printf("You can get your tickets in the lobby\n");

    }
    return 0;
}
Bodo
  • 9,287
  • 1
  • 13
  • 29
  • Your question contains some statements but not an actual question. Please [edit] your question and write what you need help with. Read the documentation of `scanf_s`. – Bodo Sep 16 '20 at 16:12
  • I can't reproduce that using `scanf(" %s', name)`. It works as expected. You should check your `scanf_s` call. – tadman Sep 16 '20 at 16:13
  • Strictly speaking letters are not necessarily placed in alphabetic order in the symbol table and there may be gaps between them. The only symbols guaranteed to be placed adjacently are `'0'` to `'9'`. – Lundin Sep 16 '20 at 16:14
  • Also, perhaps needless to say, include stdio.h and compile with a standard C compiler. – Lundin Sep 16 '20 at 16:15
  • Whether your characters are sequential depends on the character set in use. ASCII is probably in use on 95%+ of systems in use today, see [ASCII Table and Description](http://www.asciitable.com/) Older [EBCDIC](http://www.lookuptables.com/ebcdic_scancodes.php) is not sequential throughout the character ranges, but is in increasing order throughout -- thankfully. – David C. Rankin Sep 16 '20 at 16:39

1 Answers1

2

In your scanf_s(" %s", name, 2); statement, the third argument here specifies the size of the character array (name) into which to read the given response. I'm not sure why you have given 2 as that size, when you have declared, in the char name[25]; line, that you have an actual size of 25.

However, with that 2 value, the read will fail if you type in more than one character (try just giving "P" as input, and you will enter the if block).

From the documentation for scanf_s (bolding mine):

The buffer size includes the terminal null. You can use a width specification field to ensure the token that's read in fits into the buffer. When a token is too large to fit, nothing is written to the buffer unless there's a width specification.

Also, it is always a good idea to check the return value from scanf_s (and related functions), to make sure the read was successful! Adding a few check as shown in the snippet below will show you what's going on, with various different inputs:

//...
    int n = scanf_s(" %s", name, 2);
    printf("Items read = %d; Name given is: %s ...\n", n, name);
//...

With this, when I enter "Paul" as input, I see the following:

what is your last name? (Please capitalize the first letter!)
Paul
Items read = 0; Name given is:  ...
You can get your tickets in the lobby

Note: On the debate about whether or not to use scanf_s in place of scanf (as the Microsoft compiler advises), see here: Difference between scanf and scanf_s.

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
  • Got it. Changed my buffer size and it worked and also tried 'P'. Visual Stdio is telling me scanf is deprecated so I need to use scanf_s. Should your buffer size match your variable size? – Jad Driggers Sep 16 '20 at 16:38
  • You can use the `_countof` macro (defined in ``) to use the *actual* size of your character buffer(s), like this, in your case: `int n = scanf_s(" %s", name, (unsigned)_countof(name));`. – Adrian Mole Sep 16 '20 at 16:41
  • As to whether to use `scanf` or `scanf_s` ... that's a big debate (especially here on S.O.)! There are **many** folks who will scream at you for following Microsoft's 'advice', and others who will say it's OK (or even good). But that's not my call. – Adrian Mole Sep 16 '20 at 16:43
  • The *field-width* `1` would also make it usable for a 1 character read, e.g. `int n = scanf_s(" %1s", name, 2);`. Or for a one character read `*name = getchar();` and `name[1] = 0;` would nul-terminate. – David C. Rankin Sep 16 '20 at 16:47
  • @DavidC.Rankin Actually (I just tried) a field width of `2` still fails! One would need a field width of `1`. – Adrian Mole Sep 16 '20 at 16:49
  • @DavidC.Rankin Hehe - All good C/C++ coders indulge in a bit of self-slapping from time to time. (Should be incorporated into the Standards.) – Adrian Mole Sep 16 '20 at 16:53