So I'm working on a program which needs to format output. The output is supposed to be aligned, and it does do so with small numbers:
But then when I give big numbers, it no longer works:
My code is really but here's the part that prints the main output:
/* The following code prints out the data */
printf("\n\nStatistics: \n\n");
printf("Descrip\t\tNumber:\t\tTotal:\t\tAverage:\n\n");
printf("Normal\t\t%d\t\t%d\t\t%d\n\n",normal_counter,normal_total,normal_average);
printf("Short\t\t%d\t\t%d\t\t%d\n\n",short_counter,short_total,short_average);
printf("Long\t\t%d\t\t%d\t\t%d\n\n",long_counter,long_total,long_average);
printf("Overall\t\t%d\t\t%d\t\t%d\n\n",overall_counter,overall_total,overall_average);
How can I get the output to align?
Use the available printf formatter capabilities:
$ cat t.c
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
printf("%-12s%-12d%-12d\n", "a", 2989, 9283019);
printf("%-12s%-12d%-12d\n", "helloworld", 0, 1828274198);
exit(0);
}
$ gcc -Wall t.c
$ ./a.out
a 2989 9283019
helloworld 0 1828274198
As you can see, it even work with strings, so you can align your fields this way.
Related
For an assignment I have we are to find vulnerabilities in a certain C program and exploit them using various buffer overflow attacks. However when I run the .out file in the terminal with it's input argument it just stalls and doesn't do anything.
Even when I run GDB, that just lags too. I'm not looking for a solution to the assignment, I'm just looking for reasons why it's not running?
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
void partialwin()
{
printf("Achieved 1/2!\n");
}
void fullwin(){
printf("Achieved 2/2\n");
}
void vuln(){
char buffer[36];
gets(buffer);
printf("Buffer contents are %s\n",buffer);
}
int main(int argc,char**argv){
vuln();
}
Providing your sourc file is called assignment1.c and you're using gcc this should work, $ being your command prompt (which could be different on your platform)
$ gcc assignment1.c
$ a.out
Hello
Buffer contents are Hello
$
Consider the following code:
#include <stdio.h>
#include <stdlib.h>
int main() {
printf("main\n");
int a;
scanf("%d", &a);
printf("a = %d\n", a);
return 0;
}
int main1() {
printf("main1\n");
int a;
scanf("%d", &a);
printf("a = %d\n", a);
exit(0);
return 0;
}
int main2() {
printf("main2\n");
int a = getchar() - '0';
int b = getchar() - '0';
int c = getchar() - '0';
printf("a = %d\n", 100 * a + 10 * b + c);
exit(0);
return 0;
}
Assuming that the code resides in a file called test.c, the following works fine (it prints "a = 123"):
gcc -o test test.c
echo 123 | ./test
If, however, I run the program with a custom entry point, I get the dreaded Segmentation fault:
gcc -o test test.c -e"main1"
echo 123 | ./test
But if I replace the scanf with three getchars, the program runs fine again despite being run with a custom entry point:
gcc -o test test.c -e"main2"
echo 123 | ./test
To make things even more interesting, these problems occur with gcc 7.4.0 but not with gcc 4.8.4.
Any ideas?
The -e command line flag redefines the actual entry point of your program, not the “user” entry point. By default, using GCC with the GNU C standard library (glibc) this entry point is called _start, and it performs further setup before invoking the user-provided main function.
If you want to replace this entry point and continue using glibc you’ll need to perform further setup yourself. But alternatively you can use the following method to replace the main entry point, which is much simpler:
gcc -c test.c
objcopy --redefine-sym main1=main test.o
gcc -o test test.o
Note, this will only work if you don’t define main in your code, otherwise you’ll get a “multiple definition of `main'” error from the linker.
I wrote the following program to learn how \0 character works in C programs:
#include <stdio.h>
int main(void) {
char a[] = {'1','2','\0','2'};
int i=0;
for (i=0; i<4; i++){
printf("%c\n",a[i]);
}
printf("%s",a);
return 0;
}
Well, that's okay and I have the following output :
sh-4.3$ gcc -o main *.c
sh-4.3$ main
1
2
2
But when I remove \n character from printf command, I receive one additional 12 in output:
//. Same as above
for (i=0; i<4; i++){
printf("%c",a[i]);
}
//. Same as above
Output is:
12sh-4.3$ gcc -o main *.c
sh-4.3$ main
12212
While I think I must see this :
12sh-4.3$ gcc -o main *.c
sh-4.3$ main
122
Note that I used this online compiler to compile above programs. It's GNU GCC v4.8.3
The extra 12 you are getting is from the printf("%s",a); line:
Iterating through the loop prints out the characters 1, 2, null (nothing), and 2.
Printing out the string at a prints up until the null character (\0), so 12.
That's why you get the output 12212.
Printing with the newlines prints out 1, 2, new line, 2, and 12 on separate lines.
In your example you are missing the final 12 because you don't have new line at the end so your shell prompt gets printed after it: notice in your question that you have 12sh-4.3$ at the beginning of one of the lines.
Given the following code:
#include <stdio.h>
#ifndef STR
#define STR "HELLO"
#endif
int main() {
printf(STR "WORLD \n");
return 0;
}
which says: if STR was not defined, then define it to be "HELLO",
so the output will be
HELLO WORLD
How can I modify the value of STR when compiling using gcc?
I've tried
gcc -Wall program.c -DSTR="HI" -o program
but it didn't produce the expected output.
Try in the form of:
-DSTR=\"MyString\"
The source code of square.c is:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int square(int *ptr)
{
int a;
a = *ptr;
return a * a;
}
int main(int argc, char **argv)
{
int a, aa;
srandom(time(NULL));
a = random() % 10 + 1;
aa = square(&a);
printf("%d\n", aa);
return 0;
}
The command-line to compile the source code is:
gcc square.c -o square
Is it possible to run the square executable in Linux so that the printed value will not be a square of any integer number?
Any method of running the program is allowed.
Yes. We can override printf.
Write the code in your post into square.c and compile it with gcc square.c
Make this file, fakesquare.c
int printf(char *str,int i)
{
return puts("7");
}
Compile fakesquare.c as a shared library:
gcc -fPIC -o libfakesquare.so -shared fakesquare.c
Run the square program with libfakesquare.so preloaded:
[15:27:27 0 /tmp] $ LD_PRELOAD=./libfakesqare.so ./a.out
7
[15:29:16 0 /tmp] $ LD_PRELOAD=./libfakesqare.so ./a.out
7
[15:29:16 0 /tmp] $ LD_PRELOAD=./libfakesqare.so ./a.out
7
Witout libfakeshared.so preloaded:
[15:29:40 0 /tmp] $ ./a.out
36
[15:29:41 0 /tmp] $ ./a.out
16
[15:29:42 0 /tmp] $ ./a.out
64
You could use this :
Fastest way to determine if an integer's square root is an integer
Their code seems optimized, but whichever is simplest should do the trick for you.
The only dependency at your code is libc. If libc stays unmodified then your code will always work.
Also your program will fail if before running it, all available memory is exhausted. You can always check if ptr!=NULL.
Assuming a standard C environment I don't see a reason why this should fail on a standard platform. The code might fail if printf is not doing what it is inteded to do, but probably this is not what you are asking for. It also might fail on a platform where int is as small as a byte and a byte is only 6 bits wide. In this case your square function might calculate 9*9=81 which will not fit in the result type int (0..63 for 6 bit-byte). But in my opinion this is a quite academic case.