I had been studying C++ for a while now.
I'm getting in to pointers now.
But I'm creating a program on C++ that will ask for a string("%s") input.
And I want to display its character on a different line.
But when I run the program I get the wrong letters.
Here's my code;

This is C, not C++. (And, yes, I know a C++ compiler will [almost] accept it. I'm talking about idioms and convention. And the fact that main() requires a return type.)
–
Lightness Races in OrbitApr 6 '11 at 14:57

1

@shuttle87: Adding the c tag is not the solution. Let's pick one language and stick with it.
–
Lightness Races in OrbitApr 6 '11 at 14:59

1

You should also learn about indenting code. It really makes you life easier. Learn that and apply it starting today.
–
pmgApr 6 '11 at 15:00

1

@Tomalak Geret'kal: Touché. However no semicolon after *name++ doesn't seem to be legal C either. Neither is defining main with int (absent type means int in C) and not returning anything from main legal C.
–
orlpApr 6 '11 at 15:02

1

More importantly, what you can't do is learn C++ while writing C code. It's not a matter of whether or not it will work. The asker is clearly trying to learn the language (at least, that's why I study things). @Cyril: Do you have a good book about C++? That's really the best way to learn the language. There's a good list here.
–
Cody GrayApr 6 '11 at 15:03

4 Answers
4

malloc(sizeof(char)) allocates space for a single character. This is probably not what you want. As the comments below point out, the dereferencing in *name++ is pointless. It does no harm, but perhaps indicates that you're thinking incorrectly about something. name++ has the same effect.

It's been a while since I used C in anger, but isn't *name++ a perfectly common idiom for doing what is intended there?
–
Pete Apr 6 '11 at 15:01

And printf("%c", *name); rather than printf("%c", name);
–
a1ex07Apr 6 '11 at 15:02

*name++ is *(name++). The dereference is harmless, but ultimately completely pointless here. In other scenarios it may be useful if you want to output and increment at the same time.
–
Lightness Races in OrbitApr 6 '11 at 15:02

*name++ is perfectly fine. The pointer will be dereferenced first, and then the ++ operator will be applied. @Tomalak Geret'kal, he probably meant to do printf("%c", *name++);
–
Ben CollinsApr 6 '11 at 15:03

Your program is likely printing junk because you only allocate one byte to your string buffer. When the user enters a string, you will have undefined behavior because the scanf will write past the end of name.

You need to alloc name like this:

char *name = (char *)malloc(MAX_STRING_SIZE, sizeof(char));

Even better to use calloc instead of malloc. Define MAX_STRING_SIZE however you like. A reasonable size depends on the application. In your case, if the users will be entering short strings, then perhaps a reasonable buffer size is 64 bytes, or perhaps 80 or 100.

Also, in your while loop, you can increment and dereference your pointer in one step, like this:

printf("%c", *name++);

If you don't like to be that terse, then you can break them apart, but you don't need to dereference the pointer to increment it.

One advantage of using C++ and its standard libraries over C and its standard libraries is precisely this: you almost never need to use pointers.

But, taking your program for what it is worth, there are sevearal problems. First, in C++, if you want to access the C header files, you should include them with their C++ names:

#include <cstdio>
#include <cstdlib>

Next, main requires a proper signature:

int main(int, char**) {

Most crucially, you are not allocating enough space for your user's name:

name = (char *)malloc(A_BIG_ENOUGH_NUMBER);

Here, you must allocate enough space that scanf() will not write beyond the end of your buffer. But, you can't possibly know how big that is until afte scanf runs. This catch-22 is the source of "buffer-overflow" bugs. For your test program, since you control the input, it is probably OK to just pick a number bigger than any name you'll ever type. In production code, you must NEVER, EVER, used scanf in this way.

name = (char *)mallocc(40);

By the way, if you are compiling this as C code, you should never cast the return from malloc. If you are compiling this as C++ code, you must always cast the return from malloc.

printf("%c", *name); name++

This line is missing a semicolon. Did you compile this program? In future, please only post code that you have compiled. Please use your computer's cut-and-paste features to post your code, never retype the code by hand.

This line has two other problems. First, you must derefence the name pointer to access the data to which it points. (So, *name instead of name.) Second, you need not dereference name in the second statement on this line, since you do nothing with the resulting pointed-to data. (So, name++ instead of *name++.)

Tag has been changed from C++ to C. If it stays C, readers should ignore the C++-specific pieces of my answer.
–
RobᵩApr 6 '11 at 15:16

Thanks for posting this answer. It's a whole lot more useful to show and explain the differences, rather than just bantering about them in the comments. +1 from me, and definitely don't feel like you should remove it because people do drive-by tag changes.
–
Cody GrayApr 6 '11 at 15:37