C 对于以null结尾的字符串,strlen有时等于sizeof

C 对于以null结尾的字符串,strlen有时等于sizeof,c,string,null,sizeof,strlen,C,String,Null,Sizeof,Strlen,我知道strlen计算直到(不包括)空字符'\0'(或0)为止的字符数,sizeof提供了存储包括空字符在内的字符串所需的空间量,但我对代码的输出感到困惑 问题: 我希望strlen的结果始终比sizeof的结果小1,因为我的字符串以null结尾,但这似乎只适用于长度为4和8的字符串,不包括“\0”(即下面的第3和第5个结果)。我怀疑这与第1、第2和第3个结果的字符串末尾打印垃圾的原因相同。有人能解释一下这种行为吗 我读了这个相关的问题,但我不认为这里发生了什么: 代码的作用: 在main中,它

我知道
strlen
计算直到(不包括)空字符
'\0'
(或
0
)为止的字符数,
sizeof
提供了存储包括空字符在内的字符串所需的空间量,但我对代码的输出感到困惑

问题: 我希望strlen的结果始终比sizeof的结果小1,因为我的字符串以null结尾,但这似乎只适用于长度为4和8的字符串,不包括“\0”(即下面的第3和第5个结果)。我怀疑这与第1、第2和第3个结果的字符串末尾打印垃圾的原因相同。有人能解释一下这种行为吗

我读了这个相关的问题,但我不认为这里发生了什么:

代码的作用: 在
main
中,它创建一个整数数组0、2、4、6和8。然后,对于每个长度,它调用函数
make\u和\u print\u msgs

  • 创建长度为+1的字符串(对于空字符),例如,对于长度为4的字符串,将创建“aaaa\0”
  • 使用
    printf
    中的
    %c
    逐字打印消息
  • 使用
    printf
    中的
    %s
    将其打印为字符串
  • 查找字符串的
    strlen
  • 查找字符串的大小
输出: 代码: (抱歉,代码有点长,这就是我在上面解释的原因。代码中的一些注释是对Python NumPy函数的引用。)

#包括
#包括/ceil所需的*/
#包括strlen所需的/**/
void make_linspace(int a[],双开始,双停止,int num){
/*使用线性间隔的值填充数组[](就地),就像NumPy(Python)中的np.linspace一样*/
双间距=(停止-开始)/(num-1);
int i;
对于(i=0;i在代码中,
sizeof(msg)
始终等于
msglength+1
,因为您声明为
char-msg[msglength+1];

strlen(msg)
总是计数到遇到第一个
'\0'
为止。因此,在代码中,有时是
msglength+1
,有时是
msglength
,这取决于代码中未初始化的
msg

的初始内容,
sizeof(msg)
始终等于
msglength+1
,因为您声明为
char msg[msglength+1];

strlen(msg)
总是计数到遇到第一个
'\0'
为止。因此,在代码中,有时是
msglength+1
,有时是
msglength
,这取决于代码中未初始化的
msg

的初始内容,
sizeof(msg)
始终等于
msglength+1
,因为您声明为
char msg[msglength+1];

strlen(msg)
总是计数到遇到第一个
'\0'
为止。因此,在代码中,有时是
msglength+1
,有时是
msglength
,这取决于代码中未初始化的
msg

的初始内容,
sizeof(msg)
始终等于
msglength+1
,因为您声明为
char msg[msglength+1];


strlen(msg)
总是计数到遇到第一个
'\0'
为止。因此,在您的代码中,有时是
msglength+1
,有时是
msglength
,这取决于未初始化的
msg

的初始内容,将此更改为:
msg[i+1]='\0';
msg[i]='\0';

您不需要增加
i
,因为它已经被前一个
for loop
增加了


工作ideone链接:

更改此链接:
msg[i+1]='\0';
msg[i]='\0';

您不需要增加
i
,因为它已经被前一个
for loop
增加了


工作ideone链接:

更改此链接:
msg[i+1]='\0';
msg[i]='\0';

您不需要增加
i
,因为它已经被前一个
for loop
增加了


工作ideone链接:

更改此链接:
msg[i+1]='\0';
msg[i]='\0';

您不需要增加
i
,因为它已经被前一个
for loop
增加了


工作表意文字链接:

msg[i+1]='\0';
应该是
msg[i]='\0';
,因为
msglength
msg
的最后一个有效索引,
i
在循环后等于它。哦,天哪!那是一个多么愚蠢的错误。非常感谢。不要用
%d
打印
大小的值。使用
%zu
msg[i+1]='\0'
应该是
msg[i]='\0';
,因为
msglength
msg
的最后一个有效索引,
i
在循环后等于它。哦,天哪!那是一个多么愚蠢的错误。非常感谢。不要用
%d
打印
大小的值。使用
%zu
msg[i+1]='\0'
应该是
msg[i]='\0';
,因为
msglength
msg
的最后一个有效索引,
i
在循环后等于它。哦,天哪!那是一个多么愚蠢的错误。非常感谢。不要用
%d
打印
大小的值。使用
%zu
msg[i+1]='\0'
应该是
msg[i]='\0';
,因为
msglength
msg
的最后一个有效索引,
i
在循环后等于它。哦,天哪!那是一个多么愚蠢的错误。非常感谢。不要用
%d
打印类型为
size\t
的值。使用
%zu
.sizeof(msg)是msglength+1,不是msglength。@user3125367-Ouch,typo.sizeof(msg)是msglength+1,不是msglength。@user3125367-Ouch,typo.sizeof(msg)是msglength
i    data_length[i]
--------------------
0       0
msg intended to be:    
msg printed as string: �
strlen(msg): 1
sizeof(msg): 1

1       2
msg intended to be:    aa
msg printed as string: aaS
strlen(msg): 3
sizeof(msg): 3

2       4
msg intended to be:    aaaa
msg printed as string: aaaa
strlen(msg): 4
sizeof(msg): 5

3       6
msg intended to be:    aaaaaa
msg printed as string: aaaaaai
strlen(msg): 7
sizeof(msg): 7

4       8
msg intended to be:    aaaaaaaa
msg printed as string: aaaaaaaa
strlen(msg): 8
sizeof(msg): 9
#include <stdio.h>
#include <math.h>   /* needed for ceil */
#include <string.h> /* needed for strlen */

void make_linspace(int a[], double start, double stop, int num) {
    /* Fills array a[] (in place) with linearly spaced values just like np.linspace in NumPy (Python) */
    double spacing = (stop-start)/(num-1);
    int i;
    for (i=0; i<num; i++){
        a[i] = start + i*spacing;
    }
}

void make_and_print_msgs(int n_proc, int msglength)
{
    /* Create a string called msg of length msglength + 1 (for the null character '\0') */
    char msg[msglength+1];
    int i;
    printf("msg intended to be:    ");
    for (i=0; i<msglength; i++) {
        msg[i] = 'a';
        printf("%c", msg[i]);
    }
    msg[i+1] = '\0';

    /* Print message to screen as a string and fine strlen(msg) and sizeof(msg) */
    printf("\n");
    printf("msg printed as string: %s\n", msg);
    printf("strlen(msg): %d\n", strlen(msg));
    printf("sizeof(msg): %d\n\n", sizeof(msg));

}

void main(int argc, char *argv[])
{
    int n_proc = 2;

    /* Create an array containing the lengths of strings to be printed (In this case, data_length should be {0, 2, 4, 6, 8} */
    int start = 0;
    int stop_range = 10;    /* the stop value if we are using range() */
    int step = 2;             /* spacing between the integers in the output of range() */
    int stop = stop_range - step;    /* the stop value if we are using linspace() */
    int npoints = (int) ceil( ((double)stop_range - (double)start) / (double)step );  /*  number of elements in the list produced by range(start, stop_range, step)  */

    int data_length[npoints];   /* 1D array of string lengths (# of non-null chars in each str) */
    make_linspace(data_length, start, stop, npoints);
    int i;


    /* For each length, call on make_and_print_msgs to make a string of that length (plus '\0') and then print to stdout */
    printf("   i    data_length[i]\n--------------------\n");
    for (i=0; i<npoints; i++) {
        printf("%4d %7d\n", i, data_length[i]);
        make_and_print_msgs(n_proc, data_length[i]);
    }
}