tags:

views:

134

answers:

11

Right now I'm trying this:

#include <stdio.h>

int main(int argc, char *argv[]){

    if (argc != 3){

        printf("Usage: %s %s sourcecode input", argv[0], argv[1]);

    } else {

        char source[] = "This is an example.";
        int i;

        for (i = 0; i < sizeof(source); i++){

            printf("%c", source[i]);

        }

    }

    getchar();

    return 0;
}

This does also NOT work:

char *source = "This is an example.";
int i;

for (i = 0; i < strlen(source); i++){

    printf("%c", source[i]);

}

I get the error

Unhandled exception at 0x5bf714cf (msvcr100d.dll) in Test.exe: 0xC0000005: Access violation while reading at position 0x00000054.

(loosely translated from german)

So what's wrong with my code? Thanks in advance :)

A: 

Just change sizeof with strlen.

Like this:

char *source = "This is an example.";
int i;

for (i = 0; i < strlen(source); i++){

    printf("%c", source[i]);

}
Pablo Santa Cruz
this code will still have an exception because of %s and char passed to printf
ULysses
Thanks for pointing that out.
Pablo Santa Cruz
+7  A: 

You want:

for (i = 0; i < strlen(source); i++){

sizeof gives you the size of the pointer, not the string. However, it would have worked if you had declared the pointer as an array:

char source[] = "This is an example.";

but if you pass the array to function, that too will decay to a pointer. For strings it's best to always use strlen. And note what others have said about changing printf to use %c. And also, taking mmyers comments on efficiency into account, it would be better to move the call to strlen out of the loop:

int len = strlen( source );
for (i = 0; i < len; i++){

or rewrite the loop:

for (i = 0; source[i] != 0; i++){
anon
Uh, I kind of doubt he wants to use `strlen` as a bound. (Although granted, in a 10-line program it doesn't make much difference.)
Michael Myers
@mmyers Um, why not?
anon
Well, last I checked, strlen had to iterate through all characters to figure out the length. And since the char* could change in the loop, the strlen can't be hoisted out of the bounds check by the compiler; that makes the loop O(n^2) instead of O(n). Please correct me if I'm wrong.
Michael Myers
In this example, a good compiler could determine that the string does not change and omit repeated calls to strlen. But it's probably better practice to store the length in a variable prior to the loop.
R..
@Neil Butterworth: The difference between for (i=0, max=strlen(str); i<max; i++) ... and for (i=0; i < strlen(str); i++) ... is the difference between O(n^2) and O(n) (unless you've declared it as const char *str), since the upper bound needs to be evaluated for each round of the loop.
Vatine
@Valine But does it matter? anywy, changed answer to account for this.
anon
+2  A: 

sizeof(source) returns the number of bytes required by the pointer char*. You should replace it with strlen(source) which will be the length of the string you're trying to display.

Also, you should probably replace printf("%s",source[i]) with printf("%c",source[i]) since you're displaying a character.

Jacob
then... likely `printf("%c", source[i])` with `putchar(source[i])`...
ShinTakezou
A: 

Replace sizeof with strlen and it should work.

Keith Randall
A: 

you need a pointer to first char to have an ansi string.

printf("%s", source + i);

will do the job

  • of course you should have meant strlen(source), not sizeof(source)
ULysses
+4  A: 

This should work

 #include <stdio.h>
 #include <string.h>

 int main(int argc, char *argv[]){

    char *source = "This is an example.";
    int length = (int)strlen(source); //sizeof(source)=sizeof(char *) = 4 on a 32 bit implementation
    for (int i = 0; i < length; i++) 
    {

       printf("%c", source[i]);

    }


 }
Prasoon Saurav
A: 
  • sizeof(source) is returning to you the size of a char*, not the length of the string. You should be using strlen(source), and you should move that out of the loop, or else you'll be recalculating the size of the string every loop.
  • By printing with the %s format modifier, printf is looking for a char*, but you're actually passing a char. You should use the %c modifier.
JSBangs
+2  A: 
  1. sizeof() includes the terminating null character. You should use strlen() (but put the call outside the loop and save it in a variable), but that's probably not what's causing the exception.
  2. you should use "%c", not "%s" in printf - you are printing a character, not a string.
KenE
A: 

One common idiom is:

char* c = source;
while (*c) putc(*c++);

A few notes:

  • In C, strings are zero terminated. You iterate while the read character is non-zero.
  • *c++ increments c and returns the dereferenciation of the old value of c.
  • printf("%s") prints a zero-terminated string, not a char. This is the cause of your access violation.
Alexandre C.
A: 

Rather than use strlen as suggested above, you can just check for the NULL character:

#include <stdio.h>

int main(int argc, char *argv[])
{
    const char *const pszSource = "This is an example.";
    const char *pszChar = pszSource;

    while (pszChar != NULL && *pszChar != NULL)
    {
        printf("%s", *pszChar);
        ++pszChar;
    }

    getchar();

    return 0;
}
Mark Ingram
A: 

sizeof(source) returns sizeof a pointer as source is declared as char *. Correct way to use it is strlen(source).

Next:

printf("%s",source[i]); 

expects string. i.e %s expects string but you are iterating in a loop to print each character. Hence use %c.

However your way of accessing(iterating) a string using the index i is correct and hence there are no other issues in it.

Praveen S