views:

451

answers:

5

In a for loop, I am trying to use printf to print the current i value. This line: printf((char *) i); is giving me runtime errors. Why is this?!

Below is a quick fizzbuzz solution that is doing this:

void FizzBuzz()
{
    for (int i = 0; i < 20; i++)
    {
     printf((char *)i);
     if ((i % 3 == 0) && (i % 5 == 0))
     {
      printf("FizzBuzz \n");
     }
     else if (i % 3 == 0)
     {
      printf("Fizz \n");
     }
     else if (i % 5 == 0)
     {
      printf("Buzz \n");
     }
     else 
     {
      printf("%d\n", i);
     }
    }
}
+6  A: 

Because that's not how printf works. You want this instead:

printf("%d\n", i);

Or even better,

std::cout << i;
Grandpa
std::cout << i << std::endl; to write an exact equivalent of your printf line
Vinko Vrsalovic
This is definitely correct, but I'm sitll getting a runtime error and it breaks in dbghook.c..
Chris
Edit your answer with your code.
Vinko Vrsalovic
std::cout isn't better than printf. Just different.
Chris
Err... Edit your **question** with your code, Chris.
Vinko Vrsalovic
Weird, another Chris commenting on this, haha. I've edited my question with code.
Chris
`std::cout` is typesafe, and won't break on you with segfaults unless you pass it a real pointer (whereas `printf` will break if you write the format string improperly).
Pavel Minaev
+3  A: 

If you are using C++, you should use cout instead of printf:

#include <iostream>
using namespace std;

int main() {
        int i = 42;
        cout << "The answer is: " << i << endl;
}
Vinko Vrsalovic
is "using namespace stdl" required for cout? I tried using cout initially and my compiler did not recognize it, but i excluded that line.
Chris
You either do "using namespace std;" or write "std::cout << i << std::endl;" instead. Read about C++ namespaces.
Vinko Vrsalovic
+2  A: 

By that statement what you are telling is :"there is a sting starting at location i, display it " Surely that is not what you intended. Use format string %d to print a integer

Naveen
+2  A: 

The way printf works is that it takes a string like this:

printf( "the number is: " );

If you then want an integer in the last section of the string you need to use an escape character and then pass the int in as another paramater:

printf( "the number is %d", i );

There is more information here on the escape characters you can use.

You will also need to include:

#include <stdio.h>

EDIT

Sorry my terminology was wrong, % followed by a sequence is called a conversion specification not an escape characer.

HTH.

0xC0DEFACE
`%d` is not what we commonly call an escape character (`\n`, etc.).
Pierre Bourdon
ah yes you're correct. ta.
0xC0DEFACE
It's not called a "conversion specification", either, because nothing is converted by `printf` (if you pass it a `char*`, and tell it it's an `int` - e.g. `%d` - in the format string, you will get U.B.). It's called a "format specifier".
Pavel Minaev
My link to some course notes at MIT called it a conversion specification and that sounded fine to me. Either way it certainly isn't an escape character!
0xC0DEFACE
+1  A: 

The first argument of printf() is a C-style null-terminated string. It's meant to be used as a format (thus the "f") with % formatting sequences to print the remaining arguments.

By using printf((char *) i); you are instructing the computer to print every byte starting at the address that i points to, until it encounters a null. Unfortunately, given that i is usually used for counters, it probably points to very low memory. Most modern operating systems prohibit access to such memory from user-space programs to prevent bugs from creating security holes, and will send signals to offending programs. The default response to such a signal, unless you trap it, is to kill the process.

To instead display the number stored in i, use printf("%d\n", i);. To display the value of i as a character, try putc((char)i); or printf("%c\n", i);. If i really is a pointer to a character, try putc((char)(*i));.

eswald