1

我知道字符串以 NULL 结尾。但是如果字符串中间有一个空字符(\0),我该如何处理这个字符串?

#include<stdio.h>
#include<string.h>
int main(){
char *str = "App\0le";
char *str2;

printf("%c", *(str+5));
}

输出:e

  1. 字符串以空字符(\0)结尾,如何输出“e”?
  2. <string.h> 中没有函数,如何使用 str1 分配苹果?
4

4 回答 4

7

C 字符串的中间不能有空字符,因为根据定义,空字符会结束字符串。

可以使用其中一些为空字符的字符数组,但您必须将它们视为数组,而不是字符串。所以你必须自己跟踪长度。

于 2021-04-16T12:50:26.620 回答
4

字符串以空字符(\0)结尾,如何输出“e”?

字符串文字"App\0le"作为具有以下元素的未命名字符数组存储在内存中

char unnamed_string_literal[7] =  { 'A', 'p', '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
于 2021-04-16T13:23:12.860 回答
1

如果字符串中间有空字符,我该如何处理字符串?

字符串文字 "App\0le"(大小 7)以字符串 "App"大小 4)开头。

字符串总是以空字符结尾,因为 C 库将字符串定义为

字符串是由第一个空字符终止并包括第一个空字符的连续字符序列。

但是"App\0le"字符串文字

'A' 'p' 'p' '\0' 'l' 'e' '\0'

使用 OP 的代码,str只保留字符串文字的地址而不是它的大小。

char *str = "App\0le";  // str is a pointer

我们需要一些方法来收集更多信息,"App\0le"而不仅仅是使用它的地址。


字符串以空字符(\0)结尾,如何输出“e”?

字符串 确实在"App"之前结束'e',但字符串文字 "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];
}

只制作“Apple”,有选择地复制

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';
于 2021-04-16T13:41:41.907 回答
0
  1. 您正在使用指针算术访问“e”。

  2. 您可以重新编码 strdup,但您必须跟踪 str 的长度,因为根据定义,字符串是以 null 结尾的:

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));

输出:

e
于 2021-04-16T13:02:45.393 回答