我在C中制作一个id3标签编辑器.我无法弄清楚如何从二进制文件末尾拉出最后128个字节,以便操作/打印出id3标签所在的区域.下面是一些代码:
struct Tag{
char tagMark[3];
char trackName[30];
char artistName[30];
char albumName[30];
char year[4];
char comment[30];
char genre;
};
int main(int argc, char *argv[]){
struct Tag fileTag;
FILE *fp;
fp=fopen(argv[0], "r+b");
if(!fp){
printf("ERROR: File does not exist.");
}
int bufLength=129;
fseek(fp, 0, SEEK_END);
long fileLength=ftell(fp);
fseek(fp, fileLength-bufLength+1, SEEK_SET);
fread(&fileTag, sizeof(fileTag), 1, fp);
printf("%s\n", fileTag.tagMark);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我正在使用一个文件来测试它,其中包含一个格式正确的id3标记.在id3标记中,前三个字节分别包含"T","A"和"G",以便识别标记是否存在.有人知道为什么当我运行这个程序时,"_main"是打印出来的唯一东西吗?
我在C语言中定义了2个结构,包含2个int和1个char.当我打印它们的大小时,它给出的结果我无法证明.这是我的代码:
#include<stdio.h>
struct sample
{
int a:6;
int b:12;
char s;
} st;
struct name
{
int a:28;
int b:12;
char ch;
} st1;
int main()
{
int i=sizeof(st);
printf("st : %d\n\n",i);
i=sizeof(st1);
printf("st1 : %d\n\n",i);
}
Run Code Online (Sandbox Code Playgroud)
输出是:
st : 4
st1 : 8
Run Code Online (Sandbox Code Playgroud)
st的大小是4字节,st1是8字节?
我发现了类似的问题,但我得到的价值仍然不合理.根据这个问题,我的结构st应该占用3个字节,st1应该占用6个字节.
我发现了一些类似的问题,但没有一个问题有多大帮助.struct name是指向struct的第一个元素的指针,类似于数组吗?
struct example {
int foo;
int bar;
};
struct example e;
e.foo = 5;
e.bar = 10;
printf("%d\n%d\n%d\n%d\n%d\n%d\n", e, e.foo, e.bar, &e, &e.foo, &e.bar);
Run Code Online (Sandbox Code Playgroud)
输出:
5
5
10
2033501712
2033501712
2033501716
Run Code Online (Sandbox Code Playgroud)
其他问题的所有答案都说"不",但这个输出让我感到困惑.非常感谢所有的帮助.
考虑以下程序:
#include <iostream>
struct __attribute__((__packed__)) mystruct_A
{
char a;
int b;
char c;
}x;
int main()
{
std::cout<<sizeof(x)<<'\n';
}
Run Code Online (Sandbox Code Playgroud)
从这个我明白了以下几点:
我在32位环境中,正在使用Windows 7 OS。链接问题的第一个答案说,以上代码将在32位体系结构上生成6号大小的结构。
但是,当我使用g ++ 4.8.1对其进行编译时,它的输出为9。那么,结构打包在这里不会完全发生吗?为什么输出中要多出3个字节?sizeof char始终为1。在我的编译器中,sizeof int为4。因此,压缩结构时,以上结构的sizeof应该为1 + 4 + 1 = 6。
处理器有任何作用还是仅取决于编译器?
假设我有两个结构:object和widget:
struct object {
int field;
void *pointer;
};
Run Code Online (Sandbox Code Playgroud)
struct widget {
int field;
void *pointer;
};
Run Code Online (Sandbox Code Playgroud)
还有一个函数:
void consume(struct object *obj)
{
printf("(%i, %p)\n", obj->field, obj->pointer);
}
Run Code Online (Sandbox Code Playgroud)
我知道如果我尝试这样做:
struct widget wgt = {3, NULL};
consume(&wgt);
Run Code Online (Sandbox Code Playgroud)
我会违反严格的别名规则,从而产生未定义的行为。
据我了解,未定义的行为是由于编译器可能以不同的方式对齐结构字段的事实造成的:也就是说,填充字段以与地址边界对齐(但永远不会更改字段顺序,因为保证遵守该顺序)标准)。
但是如果这两个结构被打包怎么办?它们具有相同的内存布局吗?或者,换句话说,上面的代码是否consume()仍然具有未定义的行为(尽管存在持久的编译器警告)?
注意:我用于struct __attribute__((__packed__)) object { ... };打包(GCC)。
我不想用这个来骚扰你,但我在互联网上的任何地方都找不到关于“位填充”究竟是什么的详细解释,以及 StackOverflow 上与位填充相关的线程的任何答案.
我还搜索了 ISO 9899-1990,其中提到了“位填充”,但在我需要时并未对其进行解释。
我在网上找到的关于此的唯一内容是here,其中只给出了对一句话的一个可笑的简短解释,说:
位填充:
位填充是向传输或存储单元添加一个或多个额外位以使其符合标准大小。
一些来源将位填充识别为一种 位填充。
其中至少有某种信息,但对我来说还不够解释。我不太明白这到底是什么意思。它也指这个词 “位填充”。
当我在 StockOverflow 上查看“填充”的相关标签时”,填充被描述为:
插入内存结构以实现地址对齐的额外空间 - 或 - 框架和 HTML 元素内容之间的额外空间 - 或 - 使用格式化打印命令(如 C 中的 printf* 系列)打印值时的额外空间或零的功能。
我经常发现与数据类型相关的术语“位填充”,但不明白它是什么,也不知道它对这些有什么作用。
非常感谢您提供任何基于主题的答案。
typedef struct _IO_ERROR_LOG_PACKET {
UCHAR MajorFunctionCode; offset: 0 byte, size: 1 byte
UCHAR RetryCount ; offset: 1 byte, size: 1 byte
USHORT DumpDataSize ; offset: 2 byte, size: 2 byte
USHORT NumberOfStrings ; offset: 4 byte, size: 2 byte
USHORT StringOffset ; offset: 6 byte, size: 2 byte
USHORT EventCategory ; offset: 8 byte, size: 2 byte + 2 byte for alignment
NTSTATUS ErrorCode ; offset: 12 byte, size: 4 byte
ULONG UniqueErrorValue ; offset: 16 byte, size: 4 byte …Run Code Online (Sandbox Code Playgroud) 我试图使用名称空间和结构并遇到问题.
C++
#include<iostream>
using namespace std;
namespace One
{
struct Data
{
int val;
char character;
};
}
namespace Two
{
struct Data
{
int val;
bool boolean;
};
}
void functionOne(void)
{
using namespace One;
cout << "functionOne()" << endl;
cout << "The size of struct Data : ";
cout << sizeof(Data) << endl;
}
void functionTwo(void)
{
using namespace Two;
cout << "functionTwo()" << endl;
cout << "The size of struct Data : ";
cout << sizeof(Data) << …Run Code Online (Sandbox Code Playgroud) 对于实验室,我们需要使用低级别的io(open/lseek/close而不是fopen/fseek/fclose)从二进制文件读入并操作数据.我的问题是如何使用这些方法读取或编写结构.
结构如下
typedef struct Entry {
char title[33];
char artist[17];
int val;
int cost;
} Entry_T;
Run Code Online (Sandbox Code Playgroud)
我最初计划sizeof(Entry_T)简单地创建一个缓冲区并读取结构,但我不认为使用低级I/O是可能的.我应该创建4个缓冲区并按顺序填充它们,使用一个缓冲区并重新分配它以获得正确的大小,或者它是完全不同的东西.写作的一个例子也很有用,但我想在看到一个阅读例子之后我可以弄明白.
struct unaming
{
char f;
double dd;
struct
{
int data;
char c;
double d;
};
};
Run Code Online (Sandbox Code Playgroud)
我期待这个结构的大小为40个字节.但编译器返回32个字节.我期待以下布局.
[char f] [7 bytes] [double dd] [int data] [4 bytes] [char c] [7bytes] [double d] = 40
这是基于结构及其成员变量将与最大尺寸数据类型对齐的规则.
但看起来Compiler重新命令了unamed结构化.是这样的吗?为何32字节?
我有以下内容:
typedef struct
{
string city;
int temp;
}
avg_temp;
avg_temp temps[NUM_CITIES];
void sort_cities(void);
int main(void)
{
temps[0].city = "Austin";
temps[0].temp = 97;
temps[1].city = "Boston";
temps[1].temp = 82;
temps[2].city = "Chicago";
temps[2].temp = 85;
temps[3].city = "Denver";
temps[3].temp = 90;
temps[4].city = "Las Vegas";
temps[4].temp = 105;
temps[5].city = "Los Angeles";
temps[5].temp = 82;
temps[6].city = "Miami";
temps[6].temp = 97;
temps[7].city = "New York";
temps[7].temp = 85;
temps[8].city = "Phoenix";
temps[8].temp = 107;
temps[9].city = "San Francisco";
temps[9].temp = …Run Code Online (Sandbox Code Playgroud)