11

I am supposed to answer a homework question for one of my classes. Specifically, I am supposed to say if certain arrays in C are considered strings or not. Based on this article (https://www.geeksforgeeks.org/strings-in-c-2/) I know that strings are an array of characters with the null terminator at the end.

My main hangup is a part of the question that asks about an array that looks like this:

char c1[] = { 'C', 'S', '\0', '3', '2', '4', '\0' };

This is obviously an array of characters with a null terminating character at the end. However, is it still considered a string since it also has a null terminating character in the middle? How will that affect the string?

EDIT: Based on comments, I have provided the actual wording of the question:

"Which of the following arrays can be considered "strings" for the purposes of using them as arguments to strcpy(), strncpy(), strcmp(), strncmp(), and similar string functions (indicate all the apply)?"

EDIT: I emailed my professor about it since the question seemed ambiguously worded (as several people pointed out). If anyone is curious, he told me "Yes it is a string. The key is that there is a null character. But of course that will effect any string operations; the string ends at the null character."

quango
  • 137
  • 8
  • Is the question "is c1 a string?" or "does c1 contain a string?"? – EOF Feb 21 '20 at 22:04
  • @EOF the question is "Which of the following arrays can be considered "strings" for the purposes of using them as arguments to strcpy(), strncpy(), strcmp(), strncmp(), and similar string functions (indicate all the apply)?" This is the only array that I am confused about however. – quango Feb 21 '20 at 22:05
  • 4
    You might say that it is the string `"CS"` with a few bytes of garbage appended (in which case the *final* NUL character is irrelevant). But it is not a string "as a whole". -- Nevertheless, feeding this to `strcpy` etc. will not make your pc explode because these functions will "see" only the `"CS"` part. – Hagen von Eitzen Feb 21 '20 at 22:05
  • 2
    c1 can *absolutely* be used as an argument to `strcmp()`. Whether it can be used as an argument to mutating string functions depends on additional factors that are not provided. – EOF Feb 21 '20 at 22:08
  • The question is not specific enough for any answer to be "correct". **Which** argument matters for functions that modify the target string, such as `str[n]cpy()`. – Andrew Henle Feb 21 '20 at 22:21
  • 2
    The contents of `c1` are mutable, so I don't see why it would fail to be a valid destination argument for `strcpy` or similar, unless because it was not large enough to accommodate the source string. That wouldn't make it not be a string, just not a suitable one for a given purpose. – John Bollinger Feb 21 '20 at 22:39
  • 1
    Overall, I agree that the question is ambiguously worded. The expression `c1` would satisfy the basic requirements for string arguments to all the standard library's (narrow) string functions, including all those specifically named, but the behavior might not be what the caller expects or wants (even ignoring undefined behaviors that could be elicited). – John Bollinger Feb 21 '20 at 22:43
  • 1
    Note that the _type_ need not be `char`. Any _character type_ will do. – chux - Reinstate Monica Feb 21 '20 at 22:44
  • I don't think the question is ambiguous at all. `c1` is an array containing the string "CS". End of story. It also contains some leftover garbage bytes after the end, as many strings do. – Lee Daniel Crocker Feb 21 '20 at 23:00

3 Answers3

8

c1 is mostly [1] equivalent to &c1[0], which is holding one string, "CS".

There's a second string lurking in there, "324", starting at &c1[3] -- but as long as you access c1 as c1, the string "CS" is all the functions strcpy() et al. would see.


[1]: c1 is an array, &c1[0] is a pointer.

DevSolar
  • 67,862
  • 21
  • 134
  • 209
  • So, is it proper to use `c1` as the target string in a `strcpy()` command? The question is ambiguous - at best. – Andrew Henle Feb 21 '20 at 22:23
  • 1
    Of course you could use `c1` as either argument to `strcpy()`. It's a perfectly ordinary string in every sense. Ordinary strings often contain leftover garbage after their terminators. The fact that this garbage is hard-coded into the program gives the impression that the author intends to use `c1` in non-string ways, but that wasn't part of the question. – Lee Daniel Crocker Feb 21 '20 at 23:33
  • "`c1` is equivalent to `&c1[0]`" misleads. `c1` is an array. `&c1[0]` is a pointer. – chux - Reinstate Monica Feb 22 '20 at 05:35
2

If you want to know the specifics of the definition of a string in C, go to the source.

From the C90 standard:

7 Library

7.1 Introduction

7.1.1 Definitions of terms
A string is a contiguous sequence of characters terminated by and including the first null character. A “pointer to” a string is a pointer to its initial (lowest addressed) character. The “length” of a string is the number of characters preceding the null character and its “value” is the sequence of the values of the contained characters, in order.

(There were no relevant changes in later standards.)

Thus, c1 contains two consecutive strings, "CS" and "324", but is not itself a string.

If we pass an array to a function, it decays to a pointer to its first element, thus +c1 points to a string (the first one), which is good enough for any function expecting a pointer to string. It doesn't point to a string "CS\0324", but that's probably good enough for your instructors question, which is ambiguous.

Community
  • 1
  • 1
Deduplicator
  • 44,692
  • 7
  • 66
  • 118
  • 4
    I would argue that even by this definition, c1 is clearly the string "CS". Period. The fact that it might contain non-zero bytes after the terminator is irrelevant--many strings will be like that in their lifetime. – Lee Daniel Crocker Feb 21 '20 at 22:58
  • `+c1` points to a string, because `c1` begins with a string. That does not in any way, shape, or form make `c1` a string though. – Deduplicator Feb 21 '20 at 23:33
  • 2
    It's the address of a section of memory that contains some characters terminated by a zero byte. If would printf() just fine with a %s, it would give a perfectly good number passed to strlen(), would work if passed to strcpy(), etc. Sounds like a string to me. – Lee Daniel Crocker Feb 21 '20 at 23:35
  • [An array is not a pointer. It just decays to one.](https://stackoverflow.com/questions/1641957/is-an-array-name-a-pointer) – Deduplicator Feb 21 '20 at 23:38
  • Yes, but this one is two consecutive strings. Still, it might count for the instructors question, which is a bit too sloppy. – Deduplicator Feb 21 '20 at 23:47
  • Questions of definition rather than fact are often tricky, because instructors or books might choose different ones. But I think any definition of "string" in C that makes the answer to this question "no" is a bad and useless definition. – Lee Daniel Crocker Feb 21 '20 at 23:50
  • Hmpf. Choosing the definition after the fact according to the answer you want to have makes having definitions pointless. Anyway, the instructors question is ambiguous enough that you can answer both yes and no, depending on how you squint when looking. – Deduplicator Feb 22 '20 at 00:21
  • I'm agreeing with the definition you posted, which describes *a sequence of bytes in memory*, and which the sequence of bytes at address `c1` satisfies 100%. But that definition doesn't say anything about the identifier "`c1`", and the question doesn't make it clear whether we're talking about the identifier or its contents. But since C doesn't have a string type for identifiers, I think it makes sense to define a string in terms of the contents of the memory as your definition does. – Lee Daniel Crocker Feb 22 '20 at 01:06
  • `c1`, an "array 7 of char`". It contains a _string_ - even 2 strings. – chux - Reinstate Monica Feb 22 '20 at 05:48
-1

Adding to @DevSolar's answer, something I discovered after toying around with the given string, if it were to be:

char c1[] = { 'C', 'S', '\\0', '3', '2', '4', '\\0' };

If you output this string, you will get CS03240 and the size of this string is 7. As far as my understanding goes, \\0 is used to denote the null character (i.e. \0). If you do:

printf("\0");

You don't see anything on the output log, but if you do:

printf("\\0");

You see a \0, something which is expected because to output special characters such as backslashes or quotes, you need to use a \ along with them.

Something which puzzles me is the output CS03240 and it's size 7. It is common understanding that the size of a string is the number of characters in it plus one(for the null character). Also, the size is 7 even for the string, char c1[] = { 'C', 'S', '\0', '3', '2', '4', '\0' };.

So maybe a follow up to this question, what is going on here?

rasengan__
  • 883
  • 8
  • 16
  • 2
    `'\\0'` is not a _null character_. It is a multi-character constant. It has an implementation defined value certainly outside the range of `char`. `c1[]` is not a _string_ as it lacks a _null character_. "you output this string" likely results in _undefined behavior_. – chux - Reinstate Monica Feb 22 '20 at 05:43
  • I didn’t exactly get you though I looked up multi character constants. If c1[] is not a string because it does not have a null character at the end, then why is the size coming out as 7 in the initial case as posted by the OP? – rasengan__ Feb 22 '20 at 06:00
  • `char c1[] = { 'C', 'S', '\0', '3', '2', '4', '\0' };` is size 7 because it is initialized with 7 values. It _size_ has nothing to do with _strings_. `char c1[] = { 1, 2, 3, 4, 5, 6, 7 };` would still make it size 7. – chux - Reinstate Monica Feb 22 '20 at 06:08
  • As to does array `c1` contain a sting? That is a separate issue. See [also](https://stackoverflow.com/questions/60346787/what-are-the-specifics-of-the-definition-of-a-string-in-c/60349102?noredirect=1#comment106755992_60347006) – chux - Reinstate Monica Feb 22 '20 at 06:11