# Why length(str) != sizeof(str)?

**URL:** <https://discourse.julialang.org/t/why-length-str-sizeof-str/36068>\
**Category:** General Usage\
**Created:** [March 16, 2020, 10:29pm UTC](https://discourse.julialang.org/t/why-length-str-sizeof-str/36068 "2020-03-16T22:29:57Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![BMval](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bmval/32/7647_2.png) [@BMval](https://discourse.julialang.org/u/BMval)\
**Post date:** [March 16, 2020, 10:29pm UTC](https://discourse.julialang.org/t/why-length-str-sizeof-str/36068/1 "2020-03-16T22:29:57Z")

</div>

I used to use length() for string, but right now I noticed it’s not correct for big string, around 3000 characters.  
sizeof() give right result.

Why is it?

thank you in advance.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [March 16, 2020, 10:36pm UTC](https://discourse.julialang.org/t/why-length-str-sizeof-str/36068/2 "2020-03-16T22:36:12Z")

</div>

Do you have Unicode/non ASCII?

---

<div class="post-metadata">

**Author:** ![BMval](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bmval/32/7647_2.png) [@BMval](https://discourse.julialang.org/u/BMval)\
**Post date:** [March 16, 2020, 10:39pm UTC](https://discourse.julialang.org/t/why-length-str-sizeof-str/36068/3 "2020-03-16T22:39:53Z")

</div>

To be honest, I have no idea, I am just reading string from a file.

---

<div class="post-metadata">

**Author:** ![non-Jedi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/non-jedi/32/3645_2.png) [@non-Jedi](https://discourse.julialang.org/u/non-Jedi)\
**Post date:** [March 16, 2020, 11:06pm UTC](https://discourse.julialang.org/t/why-length-str-sizeof-str/36068/4 "2020-03-16T23:06:02Z")

</div>

You can use the `file` command-line utility to test. For a file that’s only ascii, `file myfile.txt` returns `myfile.txt: ASCII text` whereas with any unicode characters it will return something like `myfile.txt: UTF-8 Unicode text`. I’ve been linked to the following article before as a quick reference on the subject if you’re unaware of the difference, but I can’t vouch for it myself:

> **[The Absolute Minimum Every Software Developer Absolutely, Positively Must...](https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-positively-must-know-about-unicode-and-character-sets-no-excuses/)**
>
> Ever wonder about that mysterious Content-Type tag? You know, the one you’re supposed to put in HTML and you never quite know what it should be? Did you ever get an email from your friends in…

---

<div class="post-metadata">

**Author:** ![heliosdrm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/heliosdrm/32/3851_2.png) [@heliosdrm](https://discourse.julialang.org/u/heliosdrm)\
**Post date:** [March 16, 2020, 11:19pm UTC](https://discourse.julialang.org/t/why-length-str-sizeof-str/36068/5 "2020-03-16T23:19:56Z")

</div>

I’d say that if you are looking for the number of characters, `length` is actually the function you should use. `sizeof` gives you the size of the string in bytes, which is different if you are not using ASCII strings, as others have said.

---

<div class="post-metadata">

**Author:** ![BMval](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bmval/32/7647_2.png) [@BMval](https://discourse.julialang.org/u/BMval)\
**Post date:** [March 16, 2020, 11:21pm UTC](https://discourse.julialang.org/t/why-length-str-sizeof-str/36068/6 "2020-03-16T23:21:50Z")

</div>

So why length() give not true length ? It is less around 20 character.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [March 16, 2020, 11:25pm UTC](https://discourse.julialang.org/t/why-length-str-sizeof-str/36068/7 "2020-03-16T23:25:58Z")

</div>

Because a unicode character (length 1) may take more than one byte to store (sizeof \> 1). Now what’s the “true length” you’d like to know about.

---

<div class="post-metadata">

**Author:** ![swissr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/swissr/32/208_2.png) [@swissr](https://discourse.julialang.org/u/swissr)\
**Post date:** [March 16, 2020, 11:28pm UTC](https://discourse.julialang.org/t/why-length-str-sizeof-str/36068/8 "2020-03-16T23:28:31Z")

</div>

You should read this excellent manual chapter: [Strings · The Julia Language](https://docs.julialang.org/en/v1/manual/strings/index.html).

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [March 16, 2020, 11:28pm UTC](https://discourse.julialang.org/t/why-length-str-sizeof-str/36068/9 "2020-03-16T23:28:41Z")

</div>

As an example.

```julia
julia> length("α")
1

julia> sizeof("α")
2

```

---

<div class="post-metadata">

**Author:** ![BMval](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bmval/32/7647_2.png) [@BMval](https://discourse.julialang.org/u/BMval)\
**Post date:** [March 16, 2020, 11:29pm UTC](https://discourse.julialang.org/t/why-length-str-sizeof-str/36068/10 "2020-03-16T23:29:38Z")

</div>

yes =)) it’s true.  
so why:  
str[length(str)] !=str[end] in this case?  
but str[sizeof(str)]==str[end]

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [March 16, 2020, 11:31pm UTC](https://discourse.julialang.org/t/why-length-str-sizeof-str/36068/11 "2020-03-16T23:31:58Z")

</div>

Because string indexing is strange. Tthere are invalid indices. It’s way too complicated to explain in detaill and I don’t think I really like it either. You should read the document linked above.

Here’s an example though.

```julia
julia> s = "αb"
"αb"

julia> s[1]
'α': Unicode U+03b1 (category Ll: Letter, lowercase)

julia> s[2]
ERROR: StringIndexError("αb", 2)
Stacktrace:
 [1] string_index_err(::String, ::Int64) at ./strings/string.jl:12
 [2] getindex_continued(::String, ::Int64, ::UInt32) at ./strings/string.jl:219
 [3] getindex(::String, ::Int64) at ./strings/string.jl:212
 [4] top-level scope at REPL[3]:1

julia> s[3]
'b': ASCII/Unicode U+0062 (category Ll: Letter, lowercase)

julia> s[lastindex(s)]
'b': ASCII/Unicode U+0062 (category Ll: Letter, lowercase)

```

---

<div class="post-metadata">

**Author:** ![BMval](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bmval/32/7647_2.png) [@BMval](https://discourse.julialang.org/u/BMval)\
**Post date:** [March 16, 2020, 11:32pm UTC](https://discourse.julialang.org/t/why-length-str-sizeof-str/36068/12 "2020-03-16T23:32:13Z")

</div>

> [@yuyichao](#):
>
> (“α”

for me it’s opposite problem, I can’t reproduce it now, since string is very long, but length(str)\<sizeof(str) and str[sizeof(str)]==str[end]

so, what I have to use, to know true length of string?

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [March 16, 2020, 11:33pm UTC](https://discourse.julialang.org/t/why-length-str-sizeof-str/36068/13 "2020-03-16T23:33:05Z")

</div>

What’s opposite about it?

```julia
julia> length("α") < sizeof("α")
true

```

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [March 16, 2020, 11:34pm UTC](https://discourse.julialang.org/t/why-length-str-sizeof-str/36068/14 "2020-03-16T23:34:30Z")

</div>

> [@BMval](#):
>
> so, what I have to use, to know true length of string?

Again, what do you mean by “true length” of string. The number of characters? The number of bytes? Or something else (like the last index)?

---

<div class="post-metadata">

**Author:** ![BMval](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bmval/32/7647_2.png) [@BMval](https://discourse.julialang.org/u/BMval)\
**Post date:** [March 16, 2020, 11:34pm UTC](https://discourse.julialang.org/t/why-length-str-sizeof-str/36068/15 "2020-03-16T23:34:52Z")

</div>

but there is no:

> s=“α”  
> length(s)  
> s[sizeof(s)] - error

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [March 16, 2020, 11:35pm UTC](https://discourse.julialang.org/t/why-length-str-sizeof-str/36068/16 "2020-03-16T23:35:55Z")

</div>

> [@BMval](#):
>
> but there is no:

Well, that’s because your last character isn’t a unicode. If you want to get the last character, use `lastindex`.

---

<div class="post-metadata">

**Author:** ![BMval](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bmval/32/7647_2.png) [@BMval](https://discourse.julialang.org/u/BMval)\
**Post date:** [March 16, 2020, 11:37pm UTC](https://discourse.julialang.org/t/why-length-str-sizeof-str/36068/17 "2020-03-16T23:37:12Z")

</div>

thank you. =)) I will use lastindex(), and not length or sizeof.

---

<div class="post-metadata">

**Author:** ![heliosdrm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/heliosdrm/32/3851_2.png) [@heliosdrm](https://discourse.julialang.org/u/heliosdrm)\
**Post date:** [March 17, 2020, 11:38am UTC](https://discourse.julialang.org/t/why-length-str-sizeof-str/36068/18 "2020-03-17T11:38:01Z")

</div>

More hints that may be helpful if you want to get characters out of a non-Unicode string by their position --not only the last one:

In general, do not use `str[i]` to get the `i`-th character of `str`, unless you are sure `str` is made only of ASCII characters. `str[i]` means “the `i`-th “code unit” of `str`”, which can be different than “the `i`-th character”, and might be even a non-character code. Instead:

- Use `first(str) ` to get the first character, or `first(str, n)` for a substring with the first `n` characters.
- Likewise, use `last(str[, n])` for the last (one or `n`) characters.

If you want characters in an intermediate position, you can use `str[c1:c2]`, but previously you have to find out which are the position of the code units (`c1`, `c2`) that refer to the characters you are looking for, so:

- Use `nextind(str, 0, i)` to get the position of the `i`-th character in the string, starting from the beginning.
- Use `prevind(str, lastindex(str), i)` to get the position of the `i`-th character in the string, starting from the tail.
- If you are going to look for many characters in the string, you can make a vector with the code posistion of each character, with `charinds = collect(eachindex(str))`, such that `charinds[i]` will be the postion of the `i`-th character. (But if it is a long string, take into account that you will be allocating a vector of `Int`s as long as your string.)

You can safely iterate through the characters of a string, e.g. in a `for` loop, but do this:

```julia
for c in str
  # In the i-th iteration, `c` will always be the `i`-th character.
end

```

**Don’t** do this:

```julia
for i in 1:length(str)
  c = str[i] # This may fail, for the reasons told above.
end

```

Instead, if you want a counter of the character you are using in each iteration, do:

```julia
for (i, c) in enumerate(str)
  # In the i-th iteration, `c` will also be the `i`-th character.
end

```

or if for some reason you don’t want `i` to be a counter, but the pointer of the character in the string:

```julia
for i in eachindex(str)
  c = str[i] # This works, but `i` will not generally be 1, 2, 3...
end

```

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [March 17, 2020, 12:51pm UTC](https://discourse.julialang.org/t/why-length-str-sizeof-str/36068/19 "2020-03-17T12:51:17Z")

</div>

> [@heliosdrm](#):
>
> In general, do not use `str[i]` unless you are sure `str` is made only of ASCII characters.

`str[i]` is perfectly fine for all strings, but you should only use an `i` that is returned by a function that produces valid indices. For example, `eachindex`, `nextind`, `prevind`, `findfirst`, etcetera.

---

<div class="post-metadata">

**Author:** ![pixel27](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pixel27/32/8902_2.png) [@pixel27](https://discourse.julialang.org/u/pixel27)\
**Post date:** [March 17, 2020, 1:32pm UTC](https://discourse.julialang.org/t/why-length-str-sizeof-str/36068/20 "2020-03-17T13:32:50Z")

</div>

> [@BMval](#):
>
> so, what I have to use, to know true length of string?

What exactly do you want to know?

The number of **bytes** making up the string? `sizeof(str)`  
The number of **characters** in the string? `length(str)`

Which is the “true” length? I don’t know, depends on what you are doing with it…you probably want bytes if you are saving it, you probably want length if you are displaying it…

[Next page](https://discourse.julialang.org/t/why-length-str-sizeof-str/36068.md?page=2)
