12

Why is there no output when i run this program.

#include<stdio.h>

int main()
{
    char* t="C++";
    t[1]='p';
    t[2]='p';
    printf("%s",t);
    return 0;
}
Sadique
  • 22,572
  • 7
  • 65
  • 91
  • 10
    `main` returns `int`, not `void`. – GManNickG Mar 28 '11 at 19:43
  • 2
    Without a `'\n'` the `printf()` output might not show before the next statements execute (the stream `stdout`, by default, is line-buffered). Try `printf("%s\n", t);` or `printf("%s", t); fflush(stdout);` – pmg Mar 28 '11 at 20:17
  • @pmg: It's implementation-defined whether a text output stream requires a closing `'\n'`. If it does, then the behavior is undefined, even with `fflush(stdout)`. It's easier and more reliable just to print the newline. (On many systems, the newline isn't required, but if it's missing the output will be adjacent to the next shell prompt, which is ugly.) – Keith Thompson Jul 06 '13 at 22:47
  • I would urge you to accept Keith's answer, it is a much better answer, I have already upvoted it. – Shafik Yaghmour Feb 12 '14 at 17:27

4 Answers4

22

A C string literal creates an anonymous array of char. Any attempt to modify that array has undefined behavior. Ideally this would be enforced by making the array const, but C didn't always have const, and adding it to string literals would have broken existing code.

char* t="C++";

This is legal but potentially risky. The array containing the characters 'C', '+', '+', '\0' could be stored either in read-write memory or in read-only memory, at the whim of the compiler.

t[1]='p';

Here your program's behavior is undefined, because you're attempting to modify the contents of a string literal. The compiler isn't required to warn you about this, either at compile time or at run time -- nor is it required to do anything to make it "work".

If you want to let the compiler know that the string is read-only, it's best to add the const qualifier yourself:

const char *t = "C++";

The compiler should then at least warn you if you attempt to modify the string literal -- at least if you attempt to do so through t.

If you want to be able to modify it, you should make t a writable array:

char t[] = "C++";

Rather than making t a pointer that points to the beginning of "C++", this makes t an array into which the contents of "C++" are copied. You can do what you like with the contents of t, as long as you don't go outside its bounds.

Some more comments on your code:

#include<conio.h>

<conio.h> is specific to Windows (and MS-DOS). If you don't need your program to work on any other systems, that's fine. If you want it to be portable, remove it.

void main()

This is wrong; the correct declaration is int main(void) (int main() is questionable in C, but it's correct in C++.)

printf("%s",t);

Your output should end with a newline; various bad things can happen if it doesn't. Make this:

printf("%s\n", t);

(The question originally included this line just before the closing } :

getch();

The OP later removed it. This is Windows-specific. It's probably necessary to keep your output window from closing when the program finishes, an unfortunate problem with Windows development systems. If you want a more standard way to do this, getchar() simply reads a character from standard input, and lets you hit Enter to finish (though it doesn't give you a prompt). Or, if you're running the program either from an IDE or from a command prompt, most of them won't close the window immediately.)

Finally, since main returns a result of type int, it should actually do so; you can add

return 0;

before the closing }. This isn't really required, but it's not a bad idea. (C99 adds an implicit return 0;, but Microsoft doesn't support C99.) (Update in 2019: Microsoft's support for C99 features is slightly better. I'm not sure whether the return 0; is necessary.)

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
  • For `char s[] = "foobar";` is the copying of string literal content into array done during compilation or during runtime? – torez233 Jan 17 '22 at 06:36
  • 1
    @torez233 Yes. In the abstract machine, the string literal `"foobar"` results in the existence of a static array of type `char[7]` whose contents are copied into `s`, which is also of type `char[7]`. Depending on how `s` is defined (particularly whether it's static or not), a compiler can generate code that doesn't perform the copy, as long as the resulting behavior is correct. Nothing can refer to the address of the anonymous array corresponding to the string literal, so it needn't actually exist in memory. – Keith Thompson Jan 17 '22 at 22:16
15

"C++" is a string literal stored in read only location and hence cannot be modified. With this -

char* t="C++"; // t is pointing to a string literal stored in read only location

Instead, you should have -

char t[] = "C++" ;  // Copying the string literal to array t

to actually do -

t[1] = 'p' ;
Mahesh
  • 34,573
  • 20
  • 89
  • 115
9

There are several other problems with your code.

  1. Pointers are usually used to point to data that already exists, so you can use it like this

    char arr[] = "C++";

    char* t = &arr[0];

Also modifiable,

t[1] = 'p';

t[2] = 'p';

of course there is a special way of using string —— let the pointer point to a string constant. Just the way you used:

char *t = "C++";   // you cannot modify it in most operating systems
t[1] = 'p';
t[2] = 'p';

There is a better way of using it, which is more portable and easy to understand:

const char* t="C++"; 

2.You code have many place that is not in c standard

#include <stdio.h> // You'd better add a space between, for this is a good coding convention
#include <conio.h> // only supported by vc/vs in windows, you can use getchar() instead

int main()  // main returns int
{
    char* t = "C++";

    t[1] = 'p';
    t[2] = 'p';
    printf("%s\n", t);  // it's a good habit to add a '\n' when printing a string
    getchar();   // getchar() is supported by c standard library 

    return 0; // return 0 here
}

3.about printing string

Linux is line-buffered(ignore this if you are using windows :P) & for easier to read in console, you'd better add a '\n' at the end of you printed string:

printf("%s\n",t);

If you don't want to have a carriage return after a string. In windows use just as you like:

printf("%s",t);

In Linux, you should add a fflush() in stdlib.h.

printf("%s",t);
fflush(stdout);
adimoh
  • 658
  • 2
  • 8
  • 20
Maple
  • 138
  • 1
  • 7
  • 1
    There's nothing wrong with `char* t="C++";`. The string literal provides the "data that already exists" in the form of a statically allocated array of 4 elements. (The pointer should be `const`, but it doesn't absolutely have to be.) – Keith Thompson Jul 06 '13 at 22:33
  • `fflush` is declared in ``, not in ``. In any case, it's better to print the newline; if you don't want to, well, you should do it anyway. – Keith Thompson Jul 06 '13 at 22:48
  • `#include` is perfectly portable -- but adding a space does improve readability. There is no need to call `fflush(stdout)`, all output files are flushed when the program terminates. – Keith Thompson Jun 10 '18 at 20:25
0

Some versions of the standard runtime library require a \n to cause the output to appear.

printf("%s\n",t);
wallyk
  • 56,922
  • 16
  • 83
  • 148
  • 2
    I don't think this is the problem at all. – Sadique Mar 28 '11 at 19:46
  • 4
    Clearly. I answered the question I thought was asked. – wallyk Mar 28 '11 at 19:48
  • Well as it turns out, that's not the case. – Sadique Mar 28 '11 at 19:49
  • @Sadique: Greetings from 7 years in the future! The missing `\n` isn't the problem, but it could be an issue. "Whether the last line requires a terminating new-line character is implementation-defined." -- [N1570](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf) 7.21.2p2. If the implementation requires a terminating new-line and the program doesn't provide one, the behavior is undefined. Under both Windows and POSIX/Unix/Linux, it will just print the string without a new-line (which can be visually confusing if a shell prompt is concatenated onto your output). – Keith Thompson Jun 10 '18 at 20:30