memset在这段代码中是如何工作的

How is memset working in this snippet of code?

本文关键字:何工作 工作 段代码 代码 memset      更新时间:2023-10-16

我认为这段代码足以了解我正在做的事情。我正在使用getline从一个文本文件中读取输入数据,该文件中的行可能看起来像这样:猫很胖/喜欢唱

通过在互联网上搜索,我能够让它发挥作用,但我想更好地了解它为什么发挥作用。我的主要问题是

memcpy(id, buffer, temp - buffer); 

线路正在工作。我读过memcpy()的作用,但不了解临时缓冲区部分是如何工作的。因此,根据我的理解,我将*temp设置为该行中的"/"。然后我把行复制到其中,直到"/"。但是,在"/"减去缓冲区(即getline的整行)的温度是如何计算出来的呢?猫很胖?

希望这有点道理。

#define MAX_SIZE    255
char buffer[MAX_SIZE + 1] = { 0 };
cin.getline(buffer, MAX_SIZE);
memset(id, 0, 256);
memset(title, 0, 256);
char* temp = strchr(buffer, '/');
memcpy(id, buffer, temp - buffer);
temp++;
strcpy(title, temp);

此外,如果我可以双底,为什么MAX_SIZE定义为255,但MAX_SIZE+1经常被使用。这与行末尾的分隔符或空格有关吗?谢谢你的帮助。

在我看来,这只是一个糟糕的代码。:)我会像一样写

const size_t MAX_SIZE = 256
char buffer[MAX_SIZE] = {};
std::cin.getline( buffer, MAX_SIZE );
id[0] = '';
title[0] = '';
if ( char* temp = strchr( buffer, '/' ) )
{
    std::memcpy( id, buffer, temp - buffer );
    id[temp - buffer] = '';
    std::strcpy( title, temp + 1 );
}
else
{
    std::strcpy( id, buffer );
}

对于本声明中的memcpy

memcpy(id, buffer, temp - buffer);

然后它将临时缓冲区字节从缓冲区复制到id。由于id之前设置为零,那么在memcpy之后,它将包含一个终止为零的字符串。

您的问题涉及指针差计算,这是指示器算术中完成的算术运算家族的一部分。

大多数初学者在理解指针添加的工作原理时不会遇到太多困难。鉴于此:

char buffer[256];
char *p = buffer + 10;

通常清楚的是CCD_ 5指向CCD_。但您需要记住,类型的指针很重要。您在上面看到的相同构造也适用于更复杂的数据类型:

struct Something
{
    char name[128];
    int ident;
    int supervisor;
} people[64];
struct Something *p = people+10; // NOTE: same line, different types

和以前一样,p指向数组中的第十个元素,但注意算术;底层类型的大小用于计算相关的内存偏移量。你不需要自己做。此处不需要sizeof

那你为什么在乎呢?因为就像普通数学一样,指针数学也有某些属性,其中之一如下:

char buffer[256];
char *p = buffer+10;   // p addresses the 10th slot in the array
size_t len = p-buffer  // len is the typed-difference between p and buffer.

在这种情况下,len将是10,与p的偏移量相同。那么这和你的问题有什么关系呢?好

char* temp = strchr(buffer, '/');
memcpy(id, buffer, temp - buffer);

撇开此代码的可怕性质不谈(如果buffer数组中没有'/',则结果是tempNULL,随后的memcpy将几乎保证出现大规模segfault)。此代码在字符串中查找'/'所在的位置。一旦有了,计算temp - buffer就使用指针算术(特别是指针差分)来计算temp中的地址和作为数组基的地址之间的距离。结果是元素计数,不包括斜杠本身。因此,此代码将最多(但不包括)发现的斜线复制到id缓冲区中。id缓冲区的其余部分保留了用memset填充的所有0值,因此字符串被终止(顺便说一句,这比您需要做的工作多得多)。

在那一行之后,剩下的:

temp++;
strcpy(title, temp);

post增加临时指针,表示"移动到数组中的下一个元素"。然后CCD_ 21将空终止的CCD_ 22字符串的剩余字符复制到CCD_。值得注意的是,这可能只是:

strcpy(title, ++temp);

同样:

strcpy(title, temp+1);

其将CCD_ 24保持在CCD_。在以上所有操作中,title中的结果将是相同的:斜杠后的所有字符,但不包括它。

我希望这能解释发生了什么。祝你好运。

MAX_SIZE+1 is reserving space for the null terminator at the end of the string ('')
memcpy(id, buffer, temp - buffer) 

这是将(临时缓冲区)字节从缓冲区复制到id。由于strchr在输入中找到了"/"字符,所以临时指向缓冲区内部(假设找到了)。例如,假设缓冲区指向内存中的一个位置:

缓冲区=0x781230001

第三个字节是"/",在strchr之后,有

温度=0x781230003

temp-buffer因此为2。

HOWEVER:如果找不到"/",那么temp将无法工作,代码将崩溃。在进行指针运算之前,您应该检查strchr的结果。

您可以计算缓冲区中第一个/的位置。

char* temp = strchr(buffer, '/');

现在temp指向缓冲区中的/。若您想复制缓冲区的这一部分,那个么它就足够获取指向字符串开头和长度的指针了。因此CCD_ 30计算为长度。

=================================
The cat is fat/And likes to sing
=================================
^             ^
buffer        temp
|    length   | = temp - buffer

(或简单地为0)确定的以null结尾的字符串的末尾。因此,如果您需要存储N个字符,则需要分配N+1个缓冲区大小。