Home > front end >  C Program, printf() and strlen() argument format for output
C Program, printf() and strlen() argument format for output

Time:05-15

Why does my terminal crash when I attempt to run this C Program?

Here are the instructions for the programming exercise.

Instructions for 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.

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

CodePudding user response:

Salut, (Why can't I say "hello" at the beginning of my message?)

Why does my terminal crash when I attempt to run this C Program?

Because you don't provide enough argument in your printf function. Suddenly printf tries to read a forbidden memory area

I do not understand why there are 4 arguments

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?

CodePudding user response:

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);, the return type is size_t not int.

C11 Standard - 7.21.6.1 The fprintf function(p5) specifies:

... 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.

According to C11 Standard - 7.21.6.1 The fprintf function(p8), the d conversion specifier in "%*d" specifies:

The int argument is converted to signed decimal...

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. (the conversion specifier for size_t is zu)

C11 Standard - 7.21.6.1 The fprintf function(p9) also provides:

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)

See: Undefined, unspecified and implementation-defined behavior and What is indeterminate behavior in C ? How is it different from undefined behavior? and Undefined behavior

  • Related