strlen的有时等于sizeof为空终止字符串 [英] strlen sometimes equal to sizeof for null-terminated strings

查看:167
本文介绍了strlen的有时等于sizeof为空终止字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道的strlen 计数的字符数,直到(不包括)空字符'\\ 0'(或 0 )和的sizeof 给予储存包括空字符字符串所需要的空间量,但很困惑与我的code的输出。

问:

我预计的结果的strlen 将持续1小于的sizeof 的结果,因为我的字符串为null封端的,但它只似乎是长度为4和8的串的情况下,不包括'\\ 0'(即第3次和第5次以下的结果)。我怀疑这是由于同样的原因被印在字符串第一,第二,和第三的成绩结束了垃圾。可能有人解释这种现象?

我看了此相关的问题,但我不认为这是这里发生了什么: strlen的 - 字符串的长度增加,有时1

什么是code的作用:

,它会创建整数0,2,4,6阵列,和8。然后为每个长度,它调用的函数 make_and_print_msgs 来:


  • 创建该长度+ 1(为空字符)的字符串,例如为4的长度,将创建字符串AAAA \\ 0

  • 打印邮件字母按字母的使用%C 的printf

  • 使用打印作为一个字符串%S 的printf

  • 找到的strlen 字符串

  • 找到的sizeof 字符串

输出:

 我数据长度[I]
--------------------
0 0
味精旨在是:
味精打印为字符串:
strlen的(MSG):1
的sizeof(MSG):11 2
味精旨在是:氨基酸
味精打印成字符串:AAS
strlen的(MSG):3
的sizeof(MSG):32 4
味精旨在是:AAAA
味精打印成字符串:AAAA
strlen的(MSG):4
的sizeof(MSG):53 6
味精旨在是:AAAAAA
味精打印成字符串:aaaaaai
strlen的(MSG):7
的sizeof(MSG):74 8
味精旨在是:AAAAAAAA
味精打印成字符串:AAAAAAAA
strlen的(MSG):8
的sizeof(MSG):9

code:

(对不起code是有点长,这就是为什么我解释它上面。在code有些评论是Python的numpy的函数的引用。)

 的#include<&stdio.h中GT;
#包括LT&;&math.h中GT; / *需要CEIL * /
#包括LT&;&string.h中GT; / *需要的strlen * /无效make_linspace(int类型的[],双启动功能,双停,INT NUM){
    / *填充数组a [](的地方)与就像在numpy的(Python)的np.linspace线间隔值* /
    双间距=(制动 - 起动)/(NUM-1);
    INT I;
    对于(i = 0; I<民;我++){
        一个由[i] =启动+ I *间距;
    }
}无效make_and_print_msgs(INT n_proc,诠释msglength)
{
    / *创建一个名为长度msglength + 1的MSG(为空字符'\\ 0')的字符串* /
    字符味精[msglength + 1];
    INT I;
    输出(MSG意欲是:);
    对于(i = 0; I< msglength;我++){
        味精[I] ='A';
        的printf(%C,味精[I]);
    }
    味精[I + 1] ='\\ 0';    / *打印邮件筛选作为字符串和精细的strlen(MSG)和sizeof(MSG)* /
    的printf(\\ n);
    的printf(味精打印为字符串:%S \\ n,味精);
    的printf(strlen的(MSG)数:%d \\ n,strlen的(MSG));
    的printf(的sizeof(MSG)数:%d \\ n \\ n的sizeof(MSG));}无效的主要(INT ARGC,CHAR *的argv [])
{
    INT n_proc = 2;    / *创建包含要打印(在这种情况下字符串的长度的阵列,数据长度应该是{0,2,4,6,8} * /
    INT开始= 0;
    INT stop_range = 10; / *停止值,如果我们使用范围()* /
    INT步骤= 2; / *在范围()的输出的整数之间的间隔* /
    INT停止= stop_range - 步; / *停止值,如果我们使用linspace()* /
    INT npoints =(INT)CEIL(((双)stop_range - (双)开始)/(双)步骤); / *由范围(启动,stop_range,步骤)产生的列表中的元素数* /    INT数据长度[npoints] / * 1D字符串长度的数组(每个STR非空字符数)* /
    make_linspace(数据长度,启动,停止,npoints);
    INT I;
    / *对于每一个长度,呼吁make_and_print_msgs使该长度的字符串(加上'\\ 0'),然后打印到标准输出* /
    的printf(I数据长度[I] \\ n -------------------- \\ n);
    对于(i = 0; I< npoints;我++){
        的printf(%4D%7D \\ n,我,数据长度[I]);
        make_and_print_msgs(n_proc,数据长度[I]);
    }
}


解决方案

更改此:味精[I + 1] ='\\ 0'; 味精[I] ='\\ 0';

您不需要增加 I ,因为它已经由previous 循环递增。

工作ideone链接: http://ideone.com/GJO1q1

I know that strlen counts the number of characters up until (and excluding) the null character '\0' (or 0) and that sizeof gives the amount of space needed to store the string including the null character, but am confused with the output of my code.

Question:

I expect the result of strlen to be consistently 1 less than the result of sizeof because my strings are null-terminated, but it only seems to be the case for the string of length 4 and 8, excluding '\0' (i.e. the 3rd and 5th results below). I suspect it is the same reason that rubbish is being printed at the end of the string for 1st, 2nd, and 3rd results. Could someone explain this behavior?

I read this related question, but I don't think that's what's happening here: strlen - the length of the string is sometimes increased by 1.

What the code does:

In main, it creates an array of integers 0, 2, 4, 6, and 8. And then for each of those lengths, it calls on the function make_and_print_msgs to:

  • create a string of that length + 1 (for the null character), e.g. for a length of 4, the string "aaaa\0" is created
  • print the message letter-by-letter using %c in printf
  • print it as a string using %s in printf
  • finds the strlen of the string
  • finds the sizeof the string

Output:

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

Code:

(Sorry code is a bit long, that's why I explained it above. Some comments in the code are references to Python NumPy functions.)

#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]);
    }
}

解决方案

Change this : msg[i+1] = '\0'; to msg[i] = '\0';

You do not need to increment i as it is already incremented by the previous for loop.

Working ideone link: http://ideone.com/GJO1q1

这篇关于strlen的有时等于sizeof为空终止字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆