C 程序,用于输出的 printf() 和 strlen() 参数格式
C Program, printf() and strlen() argument format for output
为什么当我尝试 运行 这个 C 程序时我的终端会崩溃?
这是编程练习的说明。
#include <stdio.h>
#include <string.h>
int main(void)
{
char fname[20], lname[20];
printf("Please enter your first name:\n");
scanf("%s", fname);
printf("Please enter your last name:\n");
scanf("%s", lname);
printf("%s %s\n", fname, lname);
printf("%*d %*d\n", strlen(fname), strlen(lname));
printf("\n%s %s\n", fname, lname);
printf("%-*d %-*d", strlen(fname), strlen(lname));
return 0;
}
但是当我运行这样的时候它工作正常吗?我不明白为什么有两个格式说明符的控制语句后有 4 个参数。
#include <stdio.h>
#include <string.h>
int main(void)
{
char fname[20], lname[20];
printf("Please enter your first name:\n");
scanf("%s", fname);
printf("Please enter your last name:\n");
scanf("%s", lname);
printf("%s %s\n", fname, lname);
printf("%*d %*d\n", strlen(fname), strlen(fname), strlen(lname),
strlen(lname));
printf("\n%s %s\n", fname, lname);
printf("%-*d %-*d", strlen(fname), strlen(lname), strlen(lname),
strlen(lname));
return 0;
}
Salut,(为什么我不能在消息开头说“你好”?)
Why does my terminal crash when I attempt to run this C Program?
因为您没有在 printf 函数中提供足够的参数。突然 printf 试图读取一个禁止的内存区域
I do not understand why there are 4 arguments
也许这个例子可以帮助你理解:
#include <stdio.h>
#include <string.h>
int main(void)
{
char fname[20], lname[20];
int val = 9;
printf("%d stop\n", val);
val = 1;
printf("%-3d stop\n", val);
/*printf("%-6d stop\n", val);
printf("%-9d stop\n", val);
printf("%-12d stop\n", val);*/
val = 2;
printf("%-*d stop\n", 3, val);
/*printf("%-*d stop\n", 6, val);
printf("%-*d stop\n", 9, val);
printf("%-*d stop\n", 12, val);*/
char *fill = "##############################";
printf("3%.*s stop\n", 3, fill);// 3 != 3-1
/*printf("3%.*s stop\n", 6, fill);
printf("3%.*s stop\n", 9, fill);
printf("3%.*s stop\n", 12, fill);*/
return 0;
}
输出:
9 stop
1 stop
2 stop
3### stop
PS : 什么导致堆栈溢出错误?
问题是您在以下四个独立实例中调用了未定义行为:
printf("%*d %*d\n", strlen(fname), strlen(fname), strlen(lname),
strlen(lname));
strlen()
的函数原型是 size_t strlen(const char *s);
,return 类型是 size_t
而不是 int
。
C11 Standard - 7.21.6.1 The fprintf function(p5) 指定:
... a field width, or precision, or both, may be indicated by an
asterisk. In this case, an int
argument supplies the field width or
precision.
根据 C11 Standard - 7.21.6.1 The fprintf function(p8),"%*d"
中的 d
转换说明符指定:
The int
argument is converted to signed decimal...
因此在您的格式字符串中,两个 '*'
字段宽度参数中的每一个所需的类型之间以及两个 d
转换说明符中的每一个之间存在不匹配。 (size_t
的转换说明符是 zu
)
C11 Standard - 7.21.6.1 The fprintf function(p9) 还提供:
If a conversion specification is invalid, the behavior is undefined.
If any argument is not the correct type for the corresponding
conversion specification, the behavior is undefined.
所以在调用未定义的行为之后程序做什么不是由标准指定的。任何事情都可能发生。它可能看起来正常打印,根本不打印任何东西,或 SegFault(或介于两者之间的任何东西)
参见:Undefined, unspecified and implementation-defined behavior and What is indeterminate behavior in C++ ? How is it different from undefined behavior? and Undefined behavior
为什么当我尝试 运行 这个 C 程序时我的终端会崩溃?
这是编程练习的说明。
#include <stdio.h>
#include <string.h>
int main(void)
{
char fname[20], lname[20];
printf("Please enter your first name:\n");
scanf("%s", fname);
printf("Please enter your last name:\n");
scanf("%s", lname);
printf("%s %s\n", fname, lname);
printf("%*d %*d\n", strlen(fname), strlen(lname));
printf("\n%s %s\n", fname, lname);
printf("%-*d %-*d", strlen(fname), strlen(lname));
return 0;
}
但是当我运行这样的时候它工作正常吗?我不明白为什么有两个格式说明符的控制语句后有 4 个参数。
#include <stdio.h>
#include <string.h>
int main(void)
{
char fname[20], lname[20];
printf("Please enter your first name:\n");
scanf("%s", fname);
printf("Please enter your last name:\n");
scanf("%s", lname);
printf("%s %s\n", fname, lname);
printf("%*d %*d\n", strlen(fname), strlen(fname), strlen(lname),
strlen(lname));
printf("\n%s %s\n", fname, lname);
printf("%-*d %-*d", strlen(fname), strlen(lname), strlen(lname),
strlen(lname));
return 0;
}
Salut,(为什么我不能在消息开头说“你好”?)
Why does my terminal crash when I attempt to run this C Program?
因为您没有在 printf 函数中提供足够的参数。突然 printf 试图读取一个禁止的内存区域
I do not understand why there are 4 arguments
也许这个例子可以帮助你理解:
#include <stdio.h>
#include <string.h>
int main(void)
{
char fname[20], lname[20];
int val = 9;
printf("%d stop\n", val);
val = 1;
printf("%-3d stop\n", val);
/*printf("%-6d stop\n", val);
printf("%-9d stop\n", val);
printf("%-12d stop\n", val);*/
val = 2;
printf("%-*d stop\n", 3, val);
/*printf("%-*d stop\n", 6, val);
printf("%-*d stop\n", 9, val);
printf("%-*d stop\n", 12, val);*/
char *fill = "##############################";
printf("3%.*s stop\n", 3, fill);// 3 != 3-1
/*printf("3%.*s stop\n", 6, fill);
printf("3%.*s stop\n", 9, fill);
printf("3%.*s stop\n", 12, fill);*/
return 0;
}
输出:
9 stop
1 stop
2 stop
3### stop
PS : 什么导致堆栈溢出错误?
问题是您在以下四个独立实例中调用了未定义行为:
printf("%*d %*d\n", strlen(fname), strlen(fname), strlen(lname),
strlen(lname));
strlen()
的函数原型是 size_t strlen(const char *s);
,return 类型是 size_t
而不是 int
。
C11 Standard - 7.21.6.1 The fprintf function(p5) 指定:
... a field width, or precision, or both, may be indicated by an asterisk. In this case, an
int
argument supplies the field width or precision.
根据 C11 Standard - 7.21.6.1 The fprintf function(p8),"%*d"
中的 d
转换说明符指定:
The
int
argument is converted to signed decimal...
因此在您的格式字符串中,两个 '*'
字段宽度参数中的每一个所需的类型之间以及两个 d
转换说明符中的每一个之间存在不匹配。 (size_t
的转换说明符是 zu
)
C11 Standard - 7.21.6.1 The fprintf function(p9) 还提供:
If a conversion specification is invalid, the behavior is undefined. If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined.
所以在调用未定义的行为之后程序做什么不是由标准指定的。任何事情都可能发生。它可能看起来正常打印,根本不打印任何东西,或 SegFault(或介于两者之间的任何东西)
参见:Undefined, unspecified and implementation-defined behavior and What is indeterminate behavior in C++ ? How is it different from undefined behavior? and Undefined behavior