Printing a whole pointer

Viewed 86

I'm trying to get a long bunch of integers as input like :

111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003

But using arrays not allowed. So I decide to take them with the help of pointers.

0, 1, 2, 3, 4, 5, 6 each of these integers represent ‘ ’, ‘-’, ‘_’, ‘|’, ‘/’, ‘\’, ‘O‘

This means, 1 should be translated into ' '(space) or 2 should be '-'

I am asked to write a function that reads such integer files, decrypt them as above and visualize the new form. Before translating them to a new form, I want to be sure that I take them correctly and I want to be able to print them correctly, also.

char *p = malloc(1000);
scanf("%1000s",p);
for(; *p != '\n'; p++)
    printf("%c",*p);

The compiler gives me this output when I entered abc as input: abcabc

Why is that so? Is using malloc like that okay? Don't forget, arrays are not allowed!

1 Answers

Based on the description of the problem, you shouldn't need read and store 1000 characters at a time - you should be able to read each character and translate on the fly:

for ( int c = fgetc( input ); c != EOF; c = fgetc( input ) )
{ 
  // transform c and output the result here
}

You can add a print statement for debugging:

for ( int c = fgetc( input ); c != EOF; c = fgetc( input ) )
{
  fprintf( stderr, "%c", c ); 
  // transform c and output the result here
}

That's the usual approach for filters or translators like this.

Having said that, there are a few things I want to point out with your code.

As others pointed out in the comments, you need to reserve at least one element for the string terminator, so you either need to allocate 1001 elements and read 1000, or allocate 1000 elements and read 999:

char *p = malloc( 1000 );
scanf( "%999s", p );

But there's another problem - the way you've written your loop

for(; *p != '\n'; p++)
    printf("%c",*p);

you're modifying p - when you pass that as an argument to free it will fail because it's not the pointer value that malloc returned. You'll need to retain the pointer returned from malloc and either use a separate pointer to walk through the array, or use array index notation:

for ( char *tmp = p; *tmp != 0; tmp++ )
  printf( "%c", *tmp );

or

for( size_t i = 0; p[i] != 0; i++ )
  printf( "%c", p[i] );

Also, %s tells scanf to stop taking input at the next whitespace character - it will not store '\n' or any other whitespace character to the string. You'll want to read up to the 0 terminator, as I've shown above.

If you do want to include whitespace, you're better off using fgets (for this problem, you're probably better off using fgets anyway):

if ( fgets( p, 1000, input ) )
{
  // transform contents of p
}
else
{
  // error or EOF on input
}

fgets will read up to 999 characters or the newline character, whichever comes first, and properly terminate the string, so you don't need to worry about that. It will also store the newline character if there's room in the target buffer, so you need to be aware of that.

Related