问题描述
我知道字符串以 NULL 结尾。 但是如果字符串中间有一个空字符(\0),我该如何处理这个字符串?
#include<stdio.h>
#include<string.h>
int main(){
char *str = "App\0le";
char *str2;
printf("%c",*(str+5));
}
输出:e
解决方法
在 C 字符串的中间不能有空字符,因为根据定义,空字符会结束字符串。
您可以使用字符数组,其中一些是空字符,但您必须将它们视为数组,而不是字符串。所以你必须自己记录长度。
,字符串以空字符(\0)结尾,如何输出“e”?
字符串字面量 "App\0le"
作为具有以下元素的未命名字符数组存储在内存中
char unnamed_string_literal[7] = { 'A','p','\0','l','e','\0' };
本声明
char *str = "App\0le";
考虑到上述假设可以按以下方式重写
char *str = unnamed_string_literal;
因此,使用指针算术并先验地知道字符串文字中的元素数量(包括其嵌入的零字符),您可以输出表示字符串文字的字符数组的任何元素。
例如
#included <stdio.h>
int main( void )
{
char *str = "App\0le";
for (size_t i = 0; i < 7; i++)
{
if (str[i] == '\0')
{
putchar( '\\' ),putchar( '0' );
}
else
{
putchar( str[i] );
}
}
putchar( '\n' );
}
程序输出为
App\0le\0
即表达式 str[i]
是访问数组的 i-th
元素的表达式。数组的类型和存储的内容完全不重要。
如果你会写
char *str2 = str;
那么指针 str2 将指向指针 str
所指向的同一个字符串文字的第一个字符。
如果你需要获取一个字符串,那么你需要声明一个字符数组,例如
char str2[6];
并将指针 str
指向的字符串文字的字符复制到它,不包括嵌入的零字符但包括终止的零字符。您不能更改字符串文字本身,因为任何更改字符串文字的尝试都会导致未定义的行为。
例如(不使用标准 C 字符串函数)
#include <stdio.h>
int main( void )
{
char *str = "App\0le";
char str2[6];
size_t i = 0;
while (( str2[i] = str[i] ) != '\0') i++;
while (( str2[i] = str[i + 1] ) != '\0') i++;
puts( str2 );
}
程序输出为
Apple
,
如果字符串中间有空字符,如何处理字符串?
字符串文字 "App\0le"
(大小为 7)以 string "App"
(大小为 4)开头。
string 总是以 空字符 结尾,因为 C 库将字符串定义为
字符串是由第一个空字符终止并包括第一个空字符的连续字符序列。
但是 "App\0le"
是一个字符串文字
'A' 'p' 'p' '\0' 'l' 'e' '\0'
使用 OP 的代码,str
只保留字符串文字的地址,而不是它的大小。
char *str = "App\0le"; // str is a pointer
我们需要一些方法来收集有关 "App\0le"
的更多信息,而不仅仅是使用其地址。
字符串以空字符(\0)结尾,如何输出“e”?
string "App"
确实在 'e'
之前结束,但 string 文字 "App\0le"
可以进一步访问。
如何使用 str1 分配苹果?
考虑使用数组
char str_alt[] = "App\0le"; // str_alt is an array
str_alt
包含 "App\0le"
,str_alt
的大小为 7。
// Assign through copy
char str_copy[sizeof str_alt];
memcpy(str_copy,str_alt,sizeof str_alt);
// Or equivalent code
for (size_t i = 0; i < sizeof str_alt; i++) {
str_copy[i] = str_alt[i];
}
只做“苹果”,选择性复制
char str_copy2[sizeof str_alt];
size_t dest_i = 0;
for (size_t i = 0; i < sizeof str_alt; i++) {
if (str_alt[i]) {
str_copy2[dest_i++] = str_alt[i];
}
}
str_copy2[dest_i] = '\0';
,
-
您正在使用指针算法访问“e”。
-
您可以重新编码 strdup,但您必须跟踪 str 的长度,因为根据定义字符串是以空字符结尾的:
super(Child,self).__init__(a=2*x,**kwargs)
检查:
str2 = malloc(7 * sizeof(char)); // I let you handle protection
for (int i = 0; i < 7; i++) { // 7 to include the final \0
str2[i] = str[i];
}
输出:
printf("%c",*(str2+5));