0

I am writing a code to take a user's input from the terminal as a string. I've read online that the correct way to instantiate a string in C is to use an array of characters. My question is if I instantiate an array of size [10], is that 10 indexes? 10 bits? 10 bytes? See the code below:

#include <stdio.h>

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

    char str[10] = "Jessica";
    scanf("%s", &str);
    printf("%c\n", str[15]);

}

In this example "str" is initialized to size 10 and I am able to to print out str[15] assuming that when the user inputs a a string it goes up to that index.

My questions are:

  1. Does the size of the "str" array increase after taking a value from scanf?
  2. At what amount of string characters will my original array have overflow? .
Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
  • 3
    You are invoking *undefined behavior* with `printf("%c\n", str[15]);` - anything can happen in that case – UnholySheep Oct 15 '19 at 17:26
  • 1
    Possible duplicate of [No out of bounds error](https://stackoverflow.com/questions/9137157/no-out-of-bounds-error) – UnholySheep Oct 15 '19 at 17:26
  • You should read a good tutorial about array and string usage in C. Perhaps surprisingly, C doesn't have a first-class "string" type, so you often have to manipulate the individual characters yourself, and there are a number of rules you have to follow. – Steve Summit Oct 15 '19 at 17:27
  • 1
    It's 10 indexes, from `0` to `9`. Strings, by definition, are arrays with an element of value `'\0'` (or simply `0`), so the maximum characters your array can have is 9 (0 to 9 characters + the `0` element) – pmg Oct 15 '19 at 17:28
  • I know the indexes are from 0-9 but I'm confused why C is allowing me to input characters that are larger than array size 10. Say I input "abcdefghijk" that is 11 characters and I write "printf("%s\n", str);" then the whole string gets print, no out of bounds issue. Why is that? – Kaasim Shaikh Oct 15 '19 at 17:30
  • 1
    One of the ways UB raises its ugly head is by doing what you hope ... except on full moon wednesdays – pmg Oct 15 '19 at 17:31
  • 2
    C is a very effective tool for its purpose, not a safe one. Just like a chainsaw is. Your lack of error is due to that. – StoryTeller - Unslander Monica Oct 15 '19 at 17:35

3 Answers3

1

When you declare an array of char as you have done:

char str[10] = "Jessica";

then you are telling the compiler that the array will hold up to 10 values of the type char (generally - maybe even always - this is an 8-bit character). When you then try to access a 'member' of that array with an index that goes beyond the allocated size, you will get what is known as Undefined Behaviour, which means that absolutely anything may happen: your program may crash; you may get what looks like a 'sensible' value; you may find that your hard disk is entirely erased! The behaviour is undefined. So, make sure you stick within the limits you set in the declaration: for str[n] in your case, the behaviour is undefined if n < 0 or n > 9 (array indexes start at ZERO). Your code:

printf("%c\n", str[15]);

does just what I have described - it goes beyond the 'bounds' of your str array and, thus, will cause the described undefined behaviour (UB).

Also, your scanf("%s", &str); may also cause such UB, if the user enters a string of characters longer than 9 (one must be reserved for a terminating nul character)! You can prevent this by telling the scanf function to accept a maximum number of characters:

scanf("%9s", str);

where the integer given after the % is the maximum input length allowed (anything after this will be ignored). Also, as str is defined as an array, then you don't need the explicit "address of" operator (&) in scanf - it is already there, as an array reference decays to a pointer!

Hope this helps! Feel free to ask for further clarification and/or explanation.

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
  • That helped a lot. Thank you. So basically it may work but it's not the safest/reliable implementation. I have two more questions for clarity: 1. If I am taking a user input is there any way to make my array the same size as their input **without** declaring the size of the array first? 2. What would be the maximum size of a C character array? – Kaasim Shaikh Oct 15 '19 at 17:36
  • 1
    @KaasimShaikh Don't ever think it ***may*** work! It won't work, simple as that. On your other points, declare the array size to be the maximum (reasonable) length that your user would want for the string! The C standard doesn't define a maximum size (I think - but maybe it does), as such, but your compiler/builder and/or operating system may fail if you try to declare it as (say) 6 billion. – Adrian Mole Oct 15 '19 at 17:39
1

One of C's funny little foibles is that in almost all cases it does not check to make sure you are not overflowing your arrays.

It's your job to make sure you don't access outside the bounds of your arrays, and if you accidentally do, almost anything can happen. (Formally, it's undefined behavior.)

About the only thing that can't happen is that you get a nice error message

Error: array out-of-bounds access at line 23

(Well, theoretically that could happen, but in practice, virtually no C implementation checks for array bounds violations or issues messages like that.)

See also this answer to a similar question.

Steve Summit
  • 45,437
  • 7
  • 70
  • 103
1

An array declares the given number of whatever you are declaring. So in the case of:

char str[10]

You are declaring an array of ten chars.

  1. Does the size of the "str" array increase after taking a value from scanf?

No, the size does not change.

  1. At what amount of string characters will my original array have overflow?

An array of 10 chars will hold nine characters and the null terminator. So, technically, it limits the string to nine characters.

printf("%c\n", str[15]);

This code references the 16th character in your array. Because your array only holds ten characters, you are accessing memory outside of the array. It's anyone's guess as to if your program even owns that memory and, if it does, you are referencing memory that is part of another variable. This is a recipe for disaster.

Jonathan Wood
  • 65,341
  • 71
  • 269
  • 466