问题
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
inprintf
- print it as a string using
%s
inprintf
- 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]);
}
}
回答1:
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
回答2:
In your code, sizeof(msg)
always equals to msglength+1
because you declared as char msg[msglength+1];
.
strlen(msg)
always counts till the first '\0'
encountered. Thus in your code it is sometimes msglength+1
and sometimes msglength
depending on the initial content of uninitialized msg
.
来源:https://stackoverflow.com/questions/29872687/strlen-sometimes-equal-to-sizeof-for-null-terminated-strings