初学者问题:如何将char*转成字符串?
Beginner's question: How can you turn char* into a string?
我有一个名为 kmain()
的函数,它只有 1 个变量:vidmem
。这是一个 char*
类型的变量(一个字符),但我希望它是一个字符串。
这是我目前的代码:
kmain()
{
char* vidmem=(char*)0xb8000;
vidmem[0] = 'A';
vidmem[1] = 0x04;
}
如前所述,这个变量只是一个字符:A
。我怎样才能使它成为一个字符串,即 Hello, World!
?
C 中的字符串是以 null 结尾的字节序列。 A char *
指向这个序列的开始。正如我所说,这样的序列必须以 [=14=]
符号结束,即 NUL
符号。所以如果你想扩展你的代码使 vidmem
包含 Hello World,你可以这样做:
char vidmem[64]; // stack memory allocation (64 bytes)
vidmem[0] = 'H';
vidmem[1] = 'e';
vidmem[2] = 'l';
...
vidmem[11] = 'l';
vidmem[12] = 'd';
vidmem[13] = '!';
vidmem[14] = '[=10=]'; // very important
现在您可以
printf("%s", vidmem);
观察
Hello, world!
根据 2018 C 标准第 7.1.1 条第 1 款,字符串是以空字符结尾的连续字符序列,用于 C 标准库函数。要用字符 'A'
和 0x04
制作一个字符串,只需在它们后面放一个零字节即可。
也就是说,char* vidmem(char*)0xb8000;
不是正确的 C 语法。也许你的意思是 char *vidmem = (char *) 0xb8000;
。这是一个可能在特殊情况下(不同于通用多用户环境)用于定义指向内存中指定位置的指针的定义。但是,名称 vidmem
表明这可能是视频内存。字符串在视频内存中是一种不寻常的东西。此代码可能未按照您的意图执行。
别人给你解释了如何获取字符串,这是你的问题。但是,这不是您的问题。您使用 x86 并希望写入 0xB8000
处的文本缓冲区以在屏幕上显示文本。这是不正常的,因为 x86 运行 上的大多数其他程序都在 OS.
中
为了得到你想要的,你必须每隔一个字节设置你想要的字符,每隔一个字节设置你想要的颜色。字符串无法解决您的问题。
意味着您将需要这样的东西:
#define COLOR 0x04 //red text on black background
vidmem[0] = 'A';
vidmem[1] = COLOR;
vidmem[2] = 'B';
vidmem[3] = COLOR;
vidmem[4] = 'C';
vidmem[5] = COLOR;
当然,在 for
或 while
循环中执行此操作并且不要手动执行会更有意义,但我想解释一下您需要按顺序执行的操作打印一些文本。
索引位置
您可以直接访问屏幕上的各个位置。 vidmem
是一个 25 行的数组,每行是一个位置数组,每个位置有一个字节用于符号,一个字节用于颜色。您可以更改 vidmem
声明,以便一目了然地查看您访问的内容。
#define COLOR 0x04
void kmain(void) //also, use a proper declaration, with return type.
{
//vidmem is a pointer to an array with 50 elements of an array of 2 elements with type char
//The array [50][2] is exaclty the same as an array of [100], but
//with [50][2] we tell the compiler how to access it.
//The memory pointed to by vidmem has a special hardware function, so it should be volatile.
volatile char (*vidmem)[50][2]=(void*)0xb8000;
// ^----- 50 columns per line
// ^- 2 bytes per character
// V--------------- Line
// V------------ Column
// V--------- Symbol (0) or color (1)
vidmem[0][0][0] = 'A'; //symbol at position 0,0 is a 'A'
vidmem[0][0][1] = COLOR; //Set color for position 0,0
vidmem[0][1][0] = 'B'; //symbol at position 0,1 is a 'B'
vidmem[0][1][1] = COLOR; //Set color for position 0,1
//you can also directly access any other position
vidmem[1][0][0] = 'C'; //symbol at position 1,0 (second line) is a 'C'
vidmem[1][0][1] = COLOR; //Set color for position 1,0
}
我有一个名为 kmain()
的函数,它只有 1 个变量:vidmem
。这是一个 char*
类型的变量(一个字符),但我希望它是一个字符串。
这是我目前的代码:
kmain()
{
char* vidmem=(char*)0xb8000;
vidmem[0] = 'A';
vidmem[1] = 0x04;
}
如前所述,这个变量只是一个字符:A
。我怎样才能使它成为一个字符串,即 Hello, World!
?
C 中的字符串是以 null 结尾的字节序列。 A char *
指向这个序列的开始。正如我所说,这样的序列必须以 [=14=]
符号结束,即 NUL
符号。所以如果你想扩展你的代码使 vidmem
包含 Hello World,你可以这样做:
char vidmem[64]; // stack memory allocation (64 bytes)
vidmem[0] = 'H';
vidmem[1] = 'e';
vidmem[2] = 'l';
...
vidmem[11] = 'l';
vidmem[12] = 'd';
vidmem[13] = '!';
vidmem[14] = '[=10=]'; // very important
现在您可以
printf("%s", vidmem);
观察
Hello, world!
根据 2018 C 标准第 7.1.1 条第 1 款,字符串是以空字符结尾的连续字符序列,用于 C 标准库函数。要用字符 'A'
和 0x04
制作一个字符串,只需在它们后面放一个零字节即可。
也就是说,char* vidmem(char*)0xb8000;
不是正确的 C 语法。也许你的意思是 char *vidmem = (char *) 0xb8000;
。这是一个可能在特殊情况下(不同于通用多用户环境)用于定义指向内存中指定位置的指针的定义。但是,名称 vidmem
表明这可能是视频内存。字符串在视频内存中是一种不寻常的东西。此代码可能未按照您的意图执行。
别人给你解释了如何获取字符串,这是你的问题。但是,这不是您的问题。您使用 x86 并希望写入 0xB8000
处的文本缓冲区以在屏幕上显示文本。这是不正常的,因为 x86 运行 上的大多数其他程序都在 OS.
为了得到你想要的,你必须每隔一个字节设置你想要的字符,每隔一个字节设置你想要的颜色。字符串无法解决您的问题。
意味着您将需要这样的东西:
#define COLOR 0x04 //red text on black background
vidmem[0] = 'A';
vidmem[1] = COLOR;
vidmem[2] = 'B';
vidmem[3] = COLOR;
vidmem[4] = 'C';
vidmem[5] = COLOR;
当然,在 for
或 while
循环中执行此操作并且不要手动执行会更有意义,但我想解释一下您需要按顺序执行的操作打印一些文本。
索引位置
您可以直接访问屏幕上的各个位置。 vidmem
是一个 25 行的数组,每行是一个位置数组,每个位置有一个字节用于符号,一个字节用于颜色。您可以更改 vidmem
声明,以便一目了然地查看您访问的内容。
#define COLOR 0x04
void kmain(void) //also, use a proper declaration, with return type.
{
//vidmem is a pointer to an array with 50 elements of an array of 2 elements with type char
//The array [50][2] is exaclty the same as an array of [100], but
//with [50][2] we tell the compiler how to access it.
//The memory pointed to by vidmem has a special hardware function, so it should be volatile.
volatile char (*vidmem)[50][2]=(void*)0xb8000;
// ^----- 50 columns per line
// ^- 2 bytes per character
// V--------------- Line
// V------------ Column
// V--------- Symbol (0) or color (1)
vidmem[0][0][0] = 'A'; //symbol at position 0,0 is a 'A'
vidmem[0][0][1] = COLOR; //Set color for position 0,0
vidmem[0][1][0] = 'B'; //symbol at position 0,1 is a 'B'
vidmem[0][1][1] = COLOR; //Set color for position 0,1
//you can also directly access any other position
vidmem[1][0][0] = 'C'; //symbol at position 1,0 (second line) is a 'C'
vidmem[1][0][1] = COLOR; //Set color for position 1,0
}