字符串终止C-存储和匹配之间的区别

时间:2012-01-09 17:48:09

标签: c string

这可能听起来有点愚蠢,但这就是我得到它的方式,我用谷歌搜索它但没有找到相关的解决方案。

I always thought that in C, strings was terminated by '\0' 

是单个字符。 (因此我们使用单引号)

此外,我们可以做类似的事情,

while ( a[i]!='\0' )
do blah blah


which suggests that '\0'

是单个字符,理想情况下应存储在单个位置。

但是当我声明一个这样的数组时:

char a[3];

当我试图把一些价值说“嗨”时。

然后

printing a[0] gives "h"
printing a[1] gives empty space  
printing a[2] gives 0

暗示\存储在位置1和'0'位置2.尽管我们将它用作单个字符,但整个'\ 0'并未存储在一起。

为什么会这样?任何人都可以对此有所了解吗?

谢谢!

编辑:

#include <stdio.h>
void main()
{
int i=0;
char a[2];
fgets(a,sizeof(a),stdin); // Here I input "Hi".



while(a[i]!='\0')
    {
    printf("%c",a[i]);
    fflush(stdin);
    i=i+1;
    }
}

5 个答案:

答案 0 :(得分:3)

fgets将缓冲区的大小作为第二个参数,并读取减去一个字符,然后将最后一个字符设为\0。因为你的数组大小为2(对于字符串hi来说太小了,顺便说一句),fgets读取一个字符并使最后一个字符为\0,所以你有一个数组持有h\0

要使其工作,请使您的数组大小为3;一个用于h,一个用于i,另一个用于\0

#include <stdio.h>

void main() {
    int i = 0;
    char a[3];
    fgets(a, sizeof(a), stdin); // Here I input "Hi".

    while(a[i] != '\0') {
        printf("%c",a[i]);
        fflush(stdin);
        i=i+1;
    }
}

答案 1 :(得分:2)

字符串不会被字符\0终止,而是由NULL值(字符0)终止,可以通过转义序列\0表示 - 类似回车的方式可由\n表示。

答案 2 :(得分:1)

char a[2];
fgets(a,sizeof(a),stdin); // Here I input "Hi".

fgets的第二个参数旨在接收缓冲区的总长度,就像你所做的那样;但是缓冲区2 char大只够1个“有用”字符和空终止符,所以fgets只存储H并立即写'\0'({{ 1}}保证字符串终止,所以它总是更喜欢终止字符串而不是放入另一个“真实字符”但不终止字符串。)

fgets之后,你的缓冲区在内存中将如下所示:

fgets

事实上,你的程序实际上只会写出H.如果你想看到每个字符中存储的“实际数字”,你可以这样做:

+---+---+
| H |\0 |
+---+---+

,您将获得printf("%d %d", a[0], a[1]); (其中72为72 0,0为H

see example

答案 3 :(得分:0)

你肯定错过了一些代码。你是怎么把'嗨'放进变量的?我想你可能已经指定了指针而不是整个字符串(实际上是一个数组)。

您不能通过简单地分配字符串来复制字符串。在初始化时这样做(如char test[] = "hello!";)是一个特殊的例外。

char text1[] = "test"; // works (string is copied at runtime)
char text2[5]; // so far empty / content not defined
text2 = "test"; // won't work (depending on  your compiler settings it's possible there's no error, but you won't copy/assign the string)

strcpy(text2, "test"); // works, but might be unsafe (buffer overrun); requires string.h

text2[0] = 't';
text2[1] = 'e';
text2[2] = 's';
text2[3] = 't';
text2[4] = '\0'; // works too, but not recommended for longer stuff (1-2 chars is most likely okay, depending on the usage)

正如其他一些帖子中所提到的,你的问题是你的数组只能取一个长度为1的字符串(如下所述,对于一个字符串来抓取x个字符,你需要x + 1个数组元素(用于存储终止'\0')。

内存中的字符串"Hi!\0"(注意显式终止;只是为了显示)如下所示:0x00 0x48 0x69 0x21 0x00 0x00 \仅在您编写的代码中告诉编译器特殊人物将随之而来。 \不会出现在最终的程序代码中。如果您想了解更多相关内容,请阅读有关字符串文字和转义字符的教程。

答案 4 :(得分:0)

'\ 0'是escape character

要将“hi”复制到char a[3],您需要做的就是调用strcpy()库函数,如下所示。

strcpy(a,"hi");

并且strcpy()看起来像这样!

// array version
char * strcpy1(char to[], char from[])
{
        int i=0;
        while(from[i]) {
                to[i] = from[i];
                i++;
        }       
        to[i] = '\0';
        return to;
}

// pointer version
char * strcpy2(char *to, char *from)
{
        char *t = to;
        while (*to++ = *from++);
        return t;
}

希望这有帮助!