如何将存储作为用户输入的数据类型的字符串传递给 sizeof() 运算符并获取数据类型的大小?
How to pass a string that stores a datatype taken as an input from user into sizeof() operator and obtain the size of the data type?
实际上当一个数据类型,比如说int
被存储在一个字符串或者一个字符数组中,
并且字符串作为参数传递给 sizeof 运算符,程序 returns 字符数组大小而不是替换存储在字符串中的实际数据类型作为参数。
那么是否可以将字符串的内容替换为参数?
这是c
中的代码
#include <stdio.h>
int main()
{
char s[20];
printf("Please enter the data type to find it's size!: ");
scanf("%s",&s);
printf("The size of %s data type in c language is: %d",s,sizeof(s));
return 0;
}
不,那不可能。你的程序编译后就没有类型信息了(当然,调试信息可能会有,但我怀疑你想用那个)。
您可以做的一件事是创建一个大的 if 语句:
// ...
scanf("%s",&s);
size_t size;
if (strcmp(s, "int") == 0) {
size = sizeof(int);
}
else if (strcmp(s, "short") == 0) {
size = sizeof(short);
}
// ... all other types you wanna support
else {
printf("Did not recognize type %s\n", s);
return 1;
}
printf("The size of %s data type in c language is: %d ",s,size);
通过这种方式,您可以在编译时检索所有类型信息,将其显式存储在您的程序中,因此您可以访问它。
首先,sizeof
是一个编译时运算符。除了作为参数的 VLA 之外,该操作发生在编译时,因此您不能在 运行 时间内修改参数并期望它神奇地工作。
也就是说,即使可以在 运行 时求值,也没有意义,因为在编译程序中,数据类型不再(需要)存在。编译器根据数据类型分配内存(映射),并结束数据类型的存在。它不会 存在于 二进制文件中,因此您的程序没有 int
或 short
.
的概念
你能做的最好的事情是,列出可用/允许的类型/变量,比较匹配类型的输入,然后,return 应用 sizeof
运算符的结果变量/类型。
最后但并非最不重要的,sizeof
产生类型 size_t
的结果,您必须使用 %zu
格式说明符来打印结果。
没有。 sizeof
运算符直接作用于类型和变量。没办法用变量来引用类型,让sizeof
对变量引用的类型进行操作
实现大小查询程序的方法是创建支持类型及其大小的数组,然后查询:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
typedef struct {
const char *const name;
const size_t size;
} type_spec;
const type_spec known_types[] = {
{ "char", sizeof (char) }, /* Always 1 */
{ "signed char", sizeof (signed char) }, /* Always 1 */
{ "unsigned char", sizeof (unsigned char) }, /* Always 1 */
{ "short", sizeof (short) },
{ "signed short", sizeof (signed short) },
{ "unsigned short", sizeof (unsigned short) },
{ "int", sizeof (int) },
{ "signed int", sizeof (signed int) },
{ "unsigned int", sizeof (unsigned int) },
{ "long", sizeof (long) },
{ "signed long", sizeof (signed long) },
{ "unsigned long", sizeof (unsigned long) },
{ "size_t", sizeof (size_t) },
{ "off_t", sizeof (off_t) },
{ "time_t", sizeof (time_t) },
{ "float", sizeof (float) },
{ "double", sizeof (double) },
/* End of array terminator */
{ NULL, 0 }
};
size_t size_of(const char *name)
{
size_t i;
for (i = 0; known_types[i].name != NULL; i++)
if (!strcmp(name, known_types[i].name))
return known_types[i].size;
/* Unknown type name, return 0 */
return 0;
}
void list_all_types(FILE *out)
{
size_t i;
for (i = 0; known_types[i].name != NULL; i++)
fprintf(out, "sizeof (%s) == %zu\n",
known_types[i].name,
known_types[i].size);
}
请注意,因为类型名称可以包含空格,所以我不会使用 scanf()
来读取它们。我只是让用户在命令行上指定一个或多个类型,而不是:
int main(int argc, char *argv[])
{
size_t size;
int arg;
if (argc < 2) {
list_all_types(stdout);
return EXIT_SUCCESS;
}
if (!strcmp(argv[1], "-l") || !strcmp(argv[1], "--list")) {
list_all_types(stdout);
return EXIT_SUCCESS;
}
if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) {
printf("\n");
printf("Usage: %s -h | --help\n", argv[0]);
printf(" %s [ -l | --list ]\n", argv[0]);
printf(" %s type [ type ... ]\n", argv[0]);
printf("\n");
printf("This program reports the sizes of most basic\n");
printf("types supported in C.\n");
printf("\n");
return EXIT_SUCCESS;
}
for (arg = 1; arg < argc; arg++) {
size = size_of(argv[arg]);
if (!size) {
fflush(stdout);
fprintf(stderr, "%s: unsupported type.\n", argv[arg]);
return EXIT_FAILURE;
}
printf("sizeof (%s) == %zu\n", argv[arg], size);
}
return EXIT_SUCCESS;
}
known_types
数组中的列表并不详尽,但您可以轻松地将任何类型添加到数组中,每种类型一行。
.
您可以生成一个 C 程序,编译它并 运行 它。像这样:
char mytype[100] = "unsigned long long int";
int mysize;
// start the compiler
FILE *f = popen("gcc -x c -o test -", "w");
// generate the program to compile
fprintf(f, "int main(){return sizeof(%s);}", mytype);
// wait for the compiler to finish
mysize = pclose(f);
// run the compiled program and get its exit code
mysize = WEXITSTATUS(system("./test"));
// cleanup - delete the executable
remove("test");
printf("Size of %s is %d\n", mytype, mysize);
这比它的价值更麻烦 - 太多地方可能出错(系统上没有安装 gcc;当前目录不可写;等等)。
实际上当一个数据类型,比如说int
被存储在一个字符串或者一个字符数组中,
并且字符串作为参数传递给 sizeof 运算符,程序 returns 字符数组大小而不是替换存储在字符串中的实际数据类型作为参数。
那么是否可以将字符串的内容替换为参数?
这是c
中的代码#include <stdio.h>
int main()
{
char s[20];
printf("Please enter the data type to find it's size!: ");
scanf("%s",&s);
printf("The size of %s data type in c language is: %d",s,sizeof(s));
return 0;
}
不,那不可能。你的程序编译后就没有类型信息了(当然,调试信息可能会有,但我怀疑你想用那个)。
您可以做的一件事是创建一个大的 if 语句:
// ...
scanf("%s",&s);
size_t size;
if (strcmp(s, "int") == 0) {
size = sizeof(int);
}
else if (strcmp(s, "short") == 0) {
size = sizeof(short);
}
// ... all other types you wanna support
else {
printf("Did not recognize type %s\n", s);
return 1;
}
printf("The size of %s data type in c language is: %d ",s,size);
通过这种方式,您可以在编译时检索所有类型信息,将其显式存储在您的程序中,因此您可以访问它。
首先,sizeof
是一个编译时运算符。除了作为参数的 VLA 之外,该操作发生在编译时,因此您不能在 运行 时间内修改参数并期望它神奇地工作。
也就是说,即使可以在 运行 时求值,也没有意义,因为在编译程序中,数据类型不再(需要)存在。编译器根据数据类型分配内存(映射),并结束数据类型的存在。它不会 存在于 二进制文件中,因此您的程序没有 int
或 short
.
你能做的最好的事情是,列出可用/允许的类型/变量,比较匹配类型的输入,然后,return 应用 sizeof
运算符的结果变量/类型。
最后但并非最不重要的,sizeof
产生类型 size_t
的结果,您必须使用 %zu
格式说明符来打印结果。
没有。 sizeof
运算符直接作用于类型和变量。没办法用变量来引用类型,让sizeof
对变量引用的类型进行操作
实现大小查询程序的方法是创建支持类型及其大小的数组,然后查询:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
typedef struct {
const char *const name;
const size_t size;
} type_spec;
const type_spec known_types[] = {
{ "char", sizeof (char) }, /* Always 1 */
{ "signed char", sizeof (signed char) }, /* Always 1 */
{ "unsigned char", sizeof (unsigned char) }, /* Always 1 */
{ "short", sizeof (short) },
{ "signed short", sizeof (signed short) },
{ "unsigned short", sizeof (unsigned short) },
{ "int", sizeof (int) },
{ "signed int", sizeof (signed int) },
{ "unsigned int", sizeof (unsigned int) },
{ "long", sizeof (long) },
{ "signed long", sizeof (signed long) },
{ "unsigned long", sizeof (unsigned long) },
{ "size_t", sizeof (size_t) },
{ "off_t", sizeof (off_t) },
{ "time_t", sizeof (time_t) },
{ "float", sizeof (float) },
{ "double", sizeof (double) },
/* End of array terminator */
{ NULL, 0 }
};
size_t size_of(const char *name)
{
size_t i;
for (i = 0; known_types[i].name != NULL; i++)
if (!strcmp(name, known_types[i].name))
return known_types[i].size;
/* Unknown type name, return 0 */
return 0;
}
void list_all_types(FILE *out)
{
size_t i;
for (i = 0; known_types[i].name != NULL; i++)
fprintf(out, "sizeof (%s) == %zu\n",
known_types[i].name,
known_types[i].size);
}
请注意,因为类型名称可以包含空格,所以我不会使用 scanf()
来读取它们。我只是让用户在命令行上指定一个或多个类型,而不是:
int main(int argc, char *argv[])
{
size_t size;
int arg;
if (argc < 2) {
list_all_types(stdout);
return EXIT_SUCCESS;
}
if (!strcmp(argv[1], "-l") || !strcmp(argv[1], "--list")) {
list_all_types(stdout);
return EXIT_SUCCESS;
}
if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) {
printf("\n");
printf("Usage: %s -h | --help\n", argv[0]);
printf(" %s [ -l | --list ]\n", argv[0]);
printf(" %s type [ type ... ]\n", argv[0]);
printf("\n");
printf("This program reports the sizes of most basic\n");
printf("types supported in C.\n");
printf("\n");
return EXIT_SUCCESS;
}
for (arg = 1; arg < argc; arg++) {
size = size_of(argv[arg]);
if (!size) {
fflush(stdout);
fprintf(stderr, "%s: unsupported type.\n", argv[arg]);
return EXIT_FAILURE;
}
printf("sizeof (%s) == %zu\n", argv[arg], size);
}
return EXIT_SUCCESS;
}
known_types
数组中的列表并不详尽,但您可以轻松地将任何类型添加到数组中,每种类型一行。
.
您可以生成一个 C 程序,编译它并 运行 它。像这样:
char mytype[100] = "unsigned long long int";
int mysize;
// start the compiler
FILE *f = popen("gcc -x c -o test -", "w");
// generate the program to compile
fprintf(f, "int main(){return sizeof(%s);}", mytype);
// wait for the compiler to finish
mysize = pclose(f);
// run the compiled program and get its exit code
mysize = WEXITSTATUS(system("./test"));
// cleanup - delete the executable
remove("test");
printf("Size of %s is %d\n", mytype, mysize);
这比它的价值更麻烦 - 太多地方可能出错(系统上没有安装 gcc;当前目录不可写;等等)。