Unix代码中的C有什么问题
我对编写C代码相当陌生,我确信我在最基本的层面上犯了一些错误。我正在运行一个小代码来获取文件的属性,下面的函数将返回这些属性。 char*路径将包含类似“/home/etc/bin”的内容 打印路径ForStatBuff=p 53 打印路径ForStatBuff=p 53 打印路径ForStatBuff=p 53 打印路径ForStatBuff=p 53 打印路径ForStatBuff=p 53 打印路径ForStatBuff=p 53 打印路径ForStatBuff=p 53 打印路径ForStatBuff=p 53 打印路径ForStatBuff=p 53 打印路径ForStatBuff=p 53 打印路径ForStatBuff=pUnix代码中的C有什么问题,c,unix,gcc,C,Unix,Gcc,我对编写C代码相当陌生,我确信我在最基本的层面上犯了一些错误。我正在运行一个小代码来获取文件的属性,下面的函数将返回这些属性。 char*路径将包含类似“/home/etc/bin”的内容 打印路径ForStatBuff=p 53 打印路径ForStatBuff=p 53 打印路径ForStatBuff=p 53 打印路径ForStatBuff=p 53 打印路径ForStatBuff=p 53 打印路径ForStatBuff=p 53 打印路径ForStatBuff=p 53 打印路径ForS
这是我经常得到的结果,我似乎不知道我做错了什么。你们能告诉我可能是什么吗。谢谢。您正在尝试将二进制数据用作字符串。在C中,字符串以零结尾,这意味着如果一个成员为零,那么当您将其复制到缓冲区时,它将标记字符串的结尾 如果要将所有数据转换为字符串,则应使用例如
snprintf
:
char buffer[128];
snprintf(buffer, sizeof(buffer), "%d %d %d",
buf.st_dev, buf.st_ino, buf.st_mode);
有关该功能的更多信息,请参阅手册页
(在我的示例中,我只使用了结构的三个成员,添加所有需要的内容。)您在复制数据时没有进行任何转换,因此,如果buf.st_dev的最低有效字节为0(我假设为little endian),您将得到一个空字符串,从您的示例来看,LSB似乎总是“p”(113)。您可以尝试使用一个函数,将字符串和它的长度一起提供给它,然后它以十六进制打印出来,这样您就可以看到数据。您需要记住数字与其十进制表示形式之间的差异,数字231与字符串“231”没有相似性 否则,您可以执行以下操作:
sprintf(pathForStatBuf, "Dev: %d\nIno: %d\n....", buf.st_dev, buf.st_ino, ...);
缺点是缓冲区大小不容易定义
我猜您这样做只是为了了解stat和其他东西,所以您可以只分配一个大字符串(2048个字符左右),并且应该保持在范围内。乍一看,代码:
int nMalloc = sizeof(dev_t) + sizeof(ino_t) + sizeof(mode_t)+ ...
做的和
int nMalloc = sizeof(struct stat);
编辑:警告-caf指出
int nMalloc = sizeof(dev_t) + sizeof(ino_t) + ...
不一定与int nMalloc=sizeof(struct stat)完全相同代码>
struct stat
中的字段可能具有对齐约束,这会导致字段之间存在“孔”或填充。也可能存在未记录的字段。因此struct stat可能大于其已发布字段的总和
这很容易检查
if (nMalloc != sizeof(struct stat)) { fprintf(stderr, "...\n");
但将来可能会发生变化,所以您的原始版本更加健壮
根据caf的主张,这也不一定相同:
unsigned long base = 0;
memcpy(pathForStatBuff + base,&buf.st_dev,sizeof(dev_t));
base = base + sizeof(dev_t);
...
memcpy(pathForStatBuff + base,&buf.st_ctime,sizeof(time_t));
base = base + sizeof(time_t);
致:
memcpy(pathForStatBuff,&buf,sizeof(struct stat))代码>
但是尺寸测试会检测到这一点
因此,将字段分配给新结构将允许您控制所需的字段、它们的顺序以及布局的某些方面(相同的编译器/相同的平台)
如果首选memcpy,请查看。它类似于memcpy,但返回指向最后一个字节后的字节的指针,因此不需要执行以下操作:
p = memcpy(pathForStatBuf + base, ...
base = base + sizeof(...)
...
base = base + sizeof(...)
p = memcpy(pathForStatBuf + base, ...
base = base + sizeof(...)
但是要有一个额外的指针
p = memcpy(p, ...
p = memcpy(p, ...
你想得到一张可打印的表格吗?如果是这种情况,则需要使用sprintf、printf或fprintf。正如您所了解的,我会将所有memcpy转换为printf(“…,buf…,field…);
并立即查看它们,这将比第一次获得正确的字符串容易。您正在将数据复制到内存块中。唯一的问题是,您不能将printf
与%s
一起使用来显示结果,因为它不是以null结尾的字符串(或任何类型的字符串)
如果要打印内存块的内容以进行调试,可以使用十六进制打印:
{
int i;
printf("Printing pathForStatBuff = { ");
for (i = 0; i < sizeof nMalloc; i++)
printf("%#.2x ", (unsigned char)pathForStatBuff[i]);
printf("}\n");
}
{
int i;
printf(“打印路径forstatbuff={”);
对于(i=0;i
这段代码的目的到底是什么?为什么你要用memcpy
自己构建一个结构,而不仅仅是为stat
结构本身分配空间并返回它?如果你想让生成的数据的格式“可移植”“,这不是实现的方法,因为所涉及类型的endianness和大小是系统特定的……我不知道您在这里尝试做什么。你知道你可以简单地从你的函数中返回一个struct stat
,对吗?为什么它需要在char*
中?我想对文件的stat做一个MD5。这是我稍后使用上述函数MD5Init(&md5_context)的返回值运行的代码;MD5Update(&md5_上下文,returnValueOfAboveCode,strlen(returnValueOfAboveCode));MD5Final(输出和md5_上下文);所以调用MD5Update(&md5_context,(char*)&buf,sizeof(buf))代码>其中buf
是如上所述的struct stat buf
。你不需要像这样零零碎碎地复制数据,为了补充这个评论,我正在制作一个文件状态的消息摘要。MD5Update函数需要一个字符指针,因此需要将struct stat转换为char。我面临的问题是如何将数据输入到字符中。目前这对我来说很有效。但我还有另一个问题:如果我不想复制结构的所有部分,而只复制结构的几个部分,我是否需要定义自己的结构。例如,如果我不想将&buf.st_ctime复制到pathForStatBuff中该怎么办?非常感谢。答案很有帮助。我用我写的代码进行了过度杀戮。如果您想将结构复制到另一个完全相同类型的结构,可以使用赋值运算符或memcpy,但如果类型不同(意味着添加了一些字段,遗漏了一些字段,或者更改了顺序)
{
int i;
printf("Printing pathForStatBuff = { ");
for (i = 0; i < sizeof nMalloc; i++)
printf("%#.2x ", (unsigned char)pathForStatBuff[i]);
printf("}\n");
}