Additional "12" in printf output in C - c

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.

Related

how to run my own C program that prints to std out?

I only used C 2-3 times. Following hello world tutorial did not help. the function should just print to std out console.
#include <stdio.h>
void my_putstr(char* param_1) {
char *t ;
for (t = param_1; *t != '\0'; t++) {
printf("%s", t);
}
}
int main(){
my_putstr("abc");
return 0;
}
How to run this program? I do have main to call & test my putstr function.
I do this:
gcc file.c -o file
gcc file
But it still gives me the error of "main":
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
I do have the main function. What's wrong?
gcc file.c -o file
gcc file
That second line will try to compile the executable file that you created with the first line and, since it's not C source(a), that won't end too well :-)
You need to run the file with something like:
./file
And, just as an aside, you should strive to make your programs more readable, such as with:
#include <stdio.h>
// my_putstr:
// Output the given string multiple times, each time starting
// at the next character. So, for "1234", it would output
// "1234 234 34 4" (without the spaces).
void my_putstr(char *str) {
// Start at position 0, 1, m2, etc until no more string left.
for (char *ptr = str; *ptr != '\0'; ptr++) {
printf("%s", ptr);
}
}
int main(void) {
my_putstr("abc");
return 0;
}
Changes made:
Comments are quite handy if you ever come back to the code after some time;
You should try to avoid simple variable names, use names that make the intent clear (about the only exception are simple i, j, k loop variables;
The two canonical forms of main are int main(int argc, char **argv) (though the "or equivalent" phrase in the standard also allows for int main(int argc, char *argv[])) or int main(void), you should try to stick with them.
By the way, the description in the comments above is an accurate representation of the way the code works. If, instead, you just want to output a string (i.e., not the 1234 234 34 4 behaviour), you're probably better off with something like:
void my_putstr(char *str) {
// Output each character, one at a time.
for (char *ptr = str; *ptr != '\0'; ptr++)
putchar(*ptr);
// Output newline (if desired).
putchar('\n');
}
(a) The gcc program is quite capable of taking other input file types (like object files, assembler files, and so on) but I'm not sure finished executables are one of those types.

scanf produces segfault when the program is run with a custom entry point (using gcc 7.4.0)

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.

strlen(*argv) produces an unusual result

I ran the following just for fun, but cannot account for the result. Assume ./test WTF? was run at the command line, and the output produced was
WTF? 6 2. Why is there such a vast discrepancy between the reported value of argc (2 - as expected) and strlen(*argv), which came up as 6. I know an array of strings isn't exactly what strlen is looking for, however, I thought the value it produced (if it produced anything) would be reasonably close to argc. Thoughts?
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int main(int argc, char**argv)
{
for (int i = 1; i < argc; i++)
{
for (int j = 0; j < strlen(argv[i]); j++)
{
printf("%c", argv[i][j]);
}
printf(" ");
}
printf("\t%lu\t%d", strlen(*argv), argc);
printf("\n");
}
Nothing wrong here. The argv array contains two strings -
program name as invoked --> "./test"
"WTF?".
So in your example strlen(argv[0]) will print 6 and strlen(argv[1]) will print 4.
For example, if you run gcc -o myprog myprog.c in command line, you will get the followings:
argc
4
argv[0]
gcc
argv[1]
-o
argv[2]
myprog
argv[3]
myprog.c
Therefore, for your case you will get 6 (length of ./test for argv[0]) instead of 4 (length of WTF? argv[1]) as you run ./test WTF? in command line.

Read an integer from stdin (in C)

I want to write a C program that takes as input an integer, and outputs its square. Here is what I have tried.
However,
./a.out < 3 outputs 32768, and
./a.out < 4 also outputs 32768.
Where am I wrong? Thanks.
#include <stdio.h>
int main(){
int myInt;
scanf("%d", &myInt);
printf("%d\n",myInt*myInt);
}
It looks like what you're trying to do is
echo 4 | ./a.out
the syntax for < is
program < input_file
whereas | is
command_with_output | program
./a.out < 4
This tries to read the file named 4 and use it's content as input to a.out You can do it whichever way, but understand the < operator isn't for inputting the character you type quite literally.
One way to do this would be:
echo "4" > 4
./a.out < 4
I just run your program and its works great.
If you want the program receive an integer input you should use argc , argv as folowed and not use scanf.
*The code for argc argv: *
#include <stdio.h>
#include <stdlib.h>
int main(int argc , char** argv)
{
int myInt;
myInt = atoi(argv[1]);
printf("%d\n",myInt*myInt);
}
atoi - convert char* to integer.
If you want to run the program and then insert an integer, you did it right!
you can read about atoi
To run this program you should comile and run from terminal:
gcc a.c -o a
./a 3
and you will receive:
9
On the right hand side of "<", there should be a file containing the input.
try this thing:
$ echo "3" > foo
$ ./a.out < foo
Read this for more information (Specially section 5.1.2.2):
http://www.tldp.org/LDP/intro-linux/html/chap_05.html

Aligning Output Values in C

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.

Resources