简体   繁体   English

C 程序,用于输出的 printf() 和 strlen() 参数格式

[英]C Program, printf() and strlen() argument format for output

Why does my terminal crash when I attempt to run this C Program?当我尝试运行这个 C 程序时,为什么我的终端会崩溃?

Here are the instructions for the programming exercise.以下是编程练习的说明。

编程练习说明

#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;
}

But when I run it like this it works fine?但是当我这样运行它时它工作正常吗? I do not understand why there are 4 arguments after the control statement which has two format specifiers.我不明白为什么在具有两个格式说明符的控制语句之后有 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 can't I say "hello" at the beginning of my message?) Salut,(为什么我不能在消息的开头说“你好”?)

Why does my terminal crash when I attempt to run this C Program?当我尝试运行这个 C 程序时,为什么我的终端会崩溃?

Because you don't provide enough argument in your printf function.因为您没有在 printf 函数中提供足够的参数。 Suddenly printf tries to read a forbidden memory area突然 printf 试图读取一个禁止的内存区域

I do not understand why there are 4 arguments我不明白为什么有 4 个参数

Maybe this example can help you to understand :也许这个例子可以帮助你理解:

#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;
}

output:输出:

9   stop
1   stop
2   stop
3### stop

PS : What causes stack overflow errors? PS:什么导致堆栈溢出错误?

The problem is you invoke Undefined Behavior in four separate instances in:问题是您在以下四个单独的实例中调用未定义的行为

printf("%*d %*d\n", strlen(fname), strlen(fname), strlen(lname), 
strlen(lname));

The function prototype for strlen() is size_t strlen(const char *s); strlen()的函数原型是size_t strlen(const char *s); , the return type is size_t not int . ,返回类型是size_t而不是int

C11 Standard - 7.21.6.1 The fprintf function(p5) specifies: C11 标准 - 7.21.6.1 fprintf 函数 (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.在这种情况下,一个int参数提供字段宽度或精度。

According to C11 Standard - 7.21.6.1 The fprintf function(p8) , the d conversion specifier in "%*d" specifies:根据C11 标准 - 7.21.6.1 The fprintf function(p8)"%*d"中的d转换说明符指定:

The int argument is converted to signed decimal... int参数被转换为有符号十进制...

So in your format string there is a mismatch between the types required for each of the two '*' field width arguments and between each of the two d conversion specifiers.因此,在您的格式字符串中,两个'*'字段宽度参数中的每一个所需的类型之间以及两个d转换说明符中的每一个之间都存在不匹配。 (the conversion specifier for size_t is zu ) size_t的转换说明符是zu

C11 Standard - 7.21.6.1 The fprintf function(p9) also provides: C11 标准 - 7.21.6.1 fprintf 函数 (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.如果任何参数不是相应转换规范的正确类型,则行为未定义。

So what the program does after you invoke undefined behavior isn't specified by the standard.因此,在您调用未定义的行为后程序会做什么,标准并未指定。 Anything can happen.任何事情都有可能发生。 It may appear to print normally, print nothing at all, or SegFault (or anything in between)它可能看起来正常打印,根本不打印,或者 SegFault(或介于两者之间的任何东西)

See: Undefined, unspecified and implementation-defined behavior and What is indeterminate behavior in C++ ?请参阅:未定义、未指定和实现定义的行为C++ 中的不确定行为是什么? How is it different from undefined behavior?它与未定义的行为有何不同? and Undefined behavior未定义的行为

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM