C - 类型字符串越界
C - out of bounds for type string
我正在尝试解决 CS50 的一些问题集。我需要提取字符串 "stra" 的前两个字符,然后将它们连接起来并转换为字符串,然后将该字符串与数组中的字符串进行比较。我读过很多,在 C 中没有字符串,只有字符数组,但在 CS50 中它们使用字符串声明类型。当我 运行 代码时,它给了我以下错误
运行时间错误:索引 4 超出类型 'string [4]'
的范围
#include <cs50.h>
#include <stdio.h>
#include <string.h>
int main(void){
string stra = "GH7";
int x = 0;
//extract first two chars of stra
char strb[3] = {stra[0], stra[1], '[=10=]'};
//concatenate chars
string strc = strb;
string letters[] = {"AB","CD","ED","GH"};
for (int i = 0, n = sizeof(letters); i < n; i++)
{
if (strc == letters[i]) // <--the error happens here
{
break;
}
else
{
x++;
}
}
printf("%i", x);
}
它给了我这个错误
运行时间错误:索引 4 超出类型 'string [4]'
的范围
问题是初始化
n = sizeof(letters)
sizeof(letters)
应该除以单个元素(指针)的大小:
n = sizeof(letters) / sizeof(*letters)
(除非您确定 letters
指向字符串文字,这是多余的,这是计算文字数组大小的最佳方法,它甚至遵循可能的类型更改)
您想迭代元素 'string' 数组 letters
。
要计算数字元素,最好的方法是用数组的大小除以第一个元素的大小。
参见下面的示例:
//#include <cs50.h>
#include <stdio.h>
#include <string.h>
int main(void){
char *stra = "GH7";
int x = 0;
//extract first two chars of stra
char strb[3] = {stra[0], stra[1], '[=10=]'};
//concatenate chars
char *strc = strb;
printf("strc: %s\n", strc);
char * letters[] = {"AB","CD","ED","GH"};
// number of element in the `letters`
int nr_of_elements = sizeof(letters)/sizeof(letters[0]);
printf("sizeof letters= %d, sizeof the element= %d nr_of_elements= %d \n", sizeof(letters), sizeof(letters[0]), nr_of_elements);
for (int i = 0, n = nr_of_elements; i < n; i++)
{
if (strc == letters[i]) // <--the error happens here
{
break;
}
else
{
x++;
}
}
printf("x= %i", x);
return 0;
}
输出:
strc: GH
sizeof letters= 32, sizeof the element= 8 nr_of_elements= 4
x= 4
<无端咆哮>
string
是个谎言。它是类型 char *
的 typedef(别名),它 不是字符串 。 string 是一个字符序列,后跟一个 0 值终止符。字符串存储在 char
的数组中(或 wchar_t
用于 "wide" 字符串)。 char *
可能指向字符串中的第一个字符,或者它可能指向不是的序列中的第一个字符一个字符串,或者它可能指向不属于任何序列的单个字符。它绝对不是字符串。 string
类型的 object 包含 地址 ,而不是实际的字符串。
它在 CS50.h header 中的存在是混淆的根源,并且会积极阻碍您学习正确的 C 字符串语义。如果您可以选择,请不要使用它。
无端咆哮>
正如Jean-Francois指出的那样,sizeof
returns object 中的总字节数;如果要获取数组中元素的数量,则必须将数组的总大小除以单个元素的大小:
T arr[] = { /* some values of type T */ }; // for any type T
size_t count = sizeof arr / sizeof arr[0]; // or divide by sizeof *arr
记住 sizeof
是一个 运算符 ,而不是函数 - 如果操作数不是类型名称,则不需要用括号括起来 (虽然他们不受伤)。
请注意,这仅适用于数组表达式,不适用于指针。请记住,在大多数情况下,数组类型的表达式将被转换("decay")为指针类型的表达式,表达式的值将是第一个元素的地址1。如果您尝试编写一个将数组作为参数并返回计数的函数,例如
size_t elt_count( int arr[] )
{
return sizeof arr / sizeof arr[0];
}
你不会得到你所期望的,因为在这种情况下 arr
是一个指针,而不是数组2。
- 除非它是
sizeof
或一元&
运算符的操作数,或者是用于在声明中初始化字符数组的字符串文字,"N-element array of T
"类型的表达式将被转换 ("decay") 为类型 "pointer to T
" 的表达式,表达式的值将是数组第一个元素的地址。
- 在函数参数声明的上下文中,
T a[N]
和 T a[]
被解释为 T *a
;这三个都将 a
声明为指向 T
的指针。
我正在尝试解决 CS50 的一些问题集。我需要提取字符串 "stra" 的前两个字符,然后将它们连接起来并转换为字符串,然后将该字符串与数组中的字符串进行比较。我读过很多,在 C 中没有字符串,只有字符数组,但在 CS50 中它们使用字符串声明类型。当我 运行 代码时,它给了我以下错误
运行时间错误:索引 4 超出类型 'string [4]'
的范围#include <cs50.h>
#include <stdio.h>
#include <string.h>
int main(void){
string stra = "GH7";
int x = 0;
//extract first two chars of stra
char strb[3] = {stra[0], stra[1], '[=10=]'};
//concatenate chars
string strc = strb;
string letters[] = {"AB","CD","ED","GH"};
for (int i = 0, n = sizeof(letters); i < n; i++)
{
if (strc == letters[i]) // <--the error happens here
{
break;
}
else
{
x++;
}
}
printf("%i", x);
}
它给了我这个错误
运行时间错误:索引 4 超出类型 'string [4]'
的范围问题是初始化
n = sizeof(letters)
sizeof(letters)
应该除以单个元素(指针)的大小:
n = sizeof(letters) / sizeof(*letters)
(除非您确定 letters
指向字符串文字,这是多余的,这是计算文字数组大小的最佳方法,它甚至遵循可能的类型更改)
您想迭代元素 'string' 数组 letters
。
要计算数字元素,最好的方法是用数组的大小除以第一个元素的大小。
参见下面的示例:
//#include <cs50.h>
#include <stdio.h>
#include <string.h>
int main(void){
char *stra = "GH7";
int x = 0;
//extract first two chars of stra
char strb[3] = {stra[0], stra[1], '[=10=]'};
//concatenate chars
char *strc = strb;
printf("strc: %s\n", strc);
char * letters[] = {"AB","CD","ED","GH"};
// number of element in the `letters`
int nr_of_elements = sizeof(letters)/sizeof(letters[0]);
printf("sizeof letters= %d, sizeof the element= %d nr_of_elements= %d \n", sizeof(letters), sizeof(letters[0]), nr_of_elements);
for (int i = 0, n = nr_of_elements; i < n; i++)
{
if (strc == letters[i]) // <--the error happens here
{
break;
}
else
{
x++;
}
}
printf("x= %i", x);
return 0;
}
输出:
strc: GH
sizeof letters= 32, sizeof the element= 8 nr_of_elements= 4
x= 4
<无端咆哮>
string
是个谎言。它是类型 char *
的 typedef(别名),它 不是字符串 。 string 是一个字符序列,后跟一个 0 值终止符。字符串存储在 char
的数组中(或 wchar_t
用于 "wide" 字符串)。 char *
可能指向字符串中的第一个字符,或者它可能指向不是的序列中的第一个字符一个字符串,或者它可能指向不属于任何序列的单个字符。它绝对不是字符串。 string
类型的 object 包含 地址 ,而不是实际的字符串。
它在 CS50.h header 中的存在是混淆的根源,并且会积极阻碍您学习正确的 C 字符串语义。如果您可以选择,请不要使用它。
无端咆哮>
正如Jean-Francois指出的那样,sizeof
returns object 中的总字节数;如果要获取数组中元素的数量,则必须将数组的总大小除以单个元素的大小:
T arr[] = { /* some values of type T */ }; // for any type T
size_t count = sizeof arr / sizeof arr[0]; // or divide by sizeof *arr
记住 sizeof
是一个 运算符 ,而不是函数 - 如果操作数不是类型名称,则不需要用括号括起来 (虽然他们不受伤)。
请注意,这仅适用于数组表达式,不适用于指针。请记住,在大多数情况下,数组类型的表达式将被转换("decay")为指针类型的表达式,表达式的值将是第一个元素的地址1。如果您尝试编写一个将数组作为参数并返回计数的函数,例如
size_t elt_count( int arr[] )
{
return sizeof arr / sizeof arr[0];
}
你不会得到你所期望的,因为在这种情况下 arr
是一个指针,而不是数组2。
- 除非它是
sizeof
或一元&
运算符的操作数,或者是用于在声明中初始化字符数组的字符串文字,"N-element array ofT
"类型的表达式将被转换 ("decay") 为类型 "pointer toT
" 的表达式,表达式的值将是数组第一个元素的地址。 - 在函数参数声明的上下文中,
T a[N]
和T a[]
被解释为T *a
;这三个都将a
声明为指向T
的指针。