Home > Software design >  String works but prints random symbols
String works but prints random symbols

Time:09-29

I want my program to display reversed string using pointers. It is working but it is also showing random symbols. Soo.. how can I make it show only the reversed string? Example: input - hello , output - olleh.

    #include <stdio.h>

int main(void)
{
char string[30];

printf("Enter string: ");
scanf("%s",&string);
int x =sizeof(string)/sizeof(string[0]);

char *p1 = string;
char *p2 = &string[x-1];
char temp;

while(p1<=p2)
{
    temp =  *p1;
  *p1 = *p2;
  *p2 =temp;
p1  ;
p2--;
}

for(p1 =&string[0];p1<=&string[x - 1];p1  )
{
printf("%c",*p1);
}
    return 0;
}

CodePudding user response:

the problem is in calculating the string length

it does not matter the length of input this statement

int x =sizeof(string)/sizeof(string[0]);

will always return 30.

you can do two things to solve this problem

  1. you can #include<string.h> and use strlen(string) to get the actual length.
  2. you can write your own function that calculates the length and it will look like this
    int string_length(char s[]) {
       int c = 0;
    
       while (s[c] != '\0')
          c  ;
    
       return c;
    }

Sample of working code using strlen

#include <stdio.h>
#include <string.h>
int main(void)
{
char string[30];

printf("Enter string: ");
scanf("%s",string);
int x =strlen(string);
printf("%d\n", x); // here the length of the input will be printed.
char *p1 = string;
char *p2 = &string[x-1];
char temp;

while(p1<=p2)
{
    temp =  *p1;
    *p1 = *p2;
    *p2 =temp;
    p1  ;
    p2--;
}

for(p1 =&string[0];p1<=&string[x - 1];p1  ){
    printf("%c",*p1);
}
    return 0;
}

for input "asd" the result will be "dsa".

Sample of working code using string_length function

#include <stdio.h>


int string_length(char s[]) {
    int c = 0;
    
    while (s[c] != '\0')
        c  ;
    
    return c;
}

int main(void)
{
char string[30];

printf("Enter string: ");
scanf("%s",string);
int x =string_length(string);
printf("%d\n", x); // here the length of the input will be printed.
char *p1 = string;
char *p2 = &string[x-1];
char temp;

while(p1<=p2)
{
    temp =  *p1;
    *p1 = *p2;
    *p2 =temp;
    p1  ;
    p2--;
}

for(p1 =&string[0];p1<=&string[x - 1];p1  ){
    printf("%c",*p1);
}
    return 0;
}

for input "asd" the result will be "dsa".

CodePudding user response:

This call of scanf

scanf("%s",&string);

is incorrect. The second argument has the type char( * )[30] instead of char *.

You should write

scanf(")s",string);

The variable x keeps the size of the array itself instead of the stored string

int x =sizeof(string)/sizeof(string[0]);

Instead you should write

#include <string.h>

//...

size_t x = strlen( string );

The condition in the while loop should look like

while(p1 < p2)

instead of

while(p1<=p2)

because there is no great sense to swap a character with it itself.

The program can look the following way

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

int main(void)
{
    char string[30];

    printf("Enter string: ");

    if ( scanf( ")s", string ) == 1 )
    {
        char *p1 = string;
        char *p2 = string   strlen( string );

        if ( p1 != p2 )
        {
            for ( ; p1 < --p2;   p1 )
            {
                char c = *p1;
                *p1 = *p2;
                *p2 = c;
            }
        } 

        for ( p1 = string; *p1 != '\0';   p1 )
        {
            printf( "%c", *p1 );
        }
        putchar( '\n' );
    }

    return 0;
}

You could write a separate function that reverse a string using pointers. Just move the code shown in the demonstration program in a function. For example

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

char * reverse_string( char *s )
{
    char *p1 = s;
    char *p2 = s   strlen( s );

    if ( p1 != p2 )
    {
        for ( ; p1 < --p2;   p1 )
        {
            char c = *p1;
            *p1 = *p2;
            *p2 = c;
        }
    } 

   return s;
}

int main(void)
{
    char string[30];

    printf("Enter string: ");

    if ( scanf( ")s", string ) == 1 )
    {
        puts( reverse_string( string ) );
    }

    return 0;
}

CodePudding user response:

Apart from abysmal formatting of the code, the "right end" of the "string" was set to the limit of the buffer size, not the actual end of the string entered by the user.

Here's a cleaned-up, annotated version for your consideration:

#include <stdio.h>

int main() {
    char buf[100]; // name variable better

    printf("Enter string: ");
    fgets( buf, sizeof buf, stdin ); // use fgets(), not scanf()

    char *pS = buf, *pE = buf; // two pointers, initialised

    // find the end of the string with-or-without LF
    while( *pE && *pE != '\n' ) pE  ; // newline
    if( *pE == '\n' ) *pE = '\0'; // clobber possible newline
    pE--;

    // swap characters, meeting in the middle
    while( pS < pE ) {
        char tmp = *pE;
        *pE-- = *pS;
        *pS   = tmp;
    }

    printf( "%s\n", buf ); // output

    return 0;
}

You can guess what the output is like.

.ekil si tuptuo eht tahw sseug nac uoY
  •  Tags:  
  • c
  • Related