Home > Software engineering >  Argv doesnt work with char pointer on terminal
Argv doesnt work with char pointer on terminal

Time:12-19

I want to write a program that when I am on terminal and write prog.exe -u word will transform word to uppercase otherwise skip the process. but when I compile the code below, I get nothing on screen and I couldn't figure out why the error occurs.

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

char u[] = "-u";

void upper(const char *src, char *dest);

int main(int argc, char const *argv[]) {
    if (argc < 3) {
        printf("Input at least 3 argument!\n");
    } else
    if (!(strcmp(argv[1], u))) {
        char *output;
        upper(argv[2], output);
        printf("%s\n", output);
    } else {
        printf("No option\n");
    }
    return 0;
}

void upper(const char *src, char *dest) {
    while (*src) {
        if (*src >= 97 && *src <= 122) {
            *dest = *src - 32;
        } else {
            *dest = *src;
        }
        src  ;
        dest  ;
    }
    *dest = *src;
}

CodePudding user response:

The pointer output declared like

char * output;

is uninitialized and has an indeterminate value.

So using it in the function upper invokes undefined behavior.

Instead of the pointer you should use a character array large enough to store the passed string to the function.

If the compiler supports variable length arrays then you can write

char output[ strlen( argv[2] )   1 ];

And this if statement

else if( strcmp(argv[1],u) == 0 ){

will be more readable than this if statement

else if(!(strcmp(argv[1],u))){

Within the function it will be at least better to use character symbols 'a' and 'z' instead of the magic numbers 97 and 122 in the if statement

if(*src >= 97 && *src <= 122){
  *dest = *src - 32;
}

Though it is even better to use standard function islower and toupper declared in the header <ctype.h>.

The function can be declared and defined the following way

#include <ctype.h>

//...

char * upper( char *dest, const char *src )
{
    char *result = dest;

    do
    {
        if ( islower( ( unsigned char )*src ) )
        {
            *dest   = toupper( ( unsigned char )*src );
        }
        else
        {
            *dest   = *src;
        }
    } while ( *src   );

    return result;
}

CodePudding user response:

void upper(const char *src, char *dest) {
  char *tmp = dest; // hold pointer
  while(*src) {
    *dest = (*src >= 97 && *src <= 122) ? *src - 32 : src;
      src;   dest;
  }
  *dest = '\0'; // end of string
  dest = tmp;
} 

CodePudding user response:

The program has undefined behavior because you attempt to store the converted string to an uninitialized pointer output.

Note that using hard coded constants such as 97, 122 and 32 is both confusing and non portable to non-ASCII environments. You should use the macros and functions from <ctype.h> for readability and portability.

You could simply modify the argument string in place this way:

#include <ctype.h>
#include <stdio.h>

void upper(char *str);

int main(int argc, char *argv[]) {
    if (argc < 3) {
        printf("Input at least 3 arguments!\n");
    } else
    if (!(strcmp(argv[1], "-u"))) {
        printf("%s\n", upper(argv[2]));
    } else {
        printf("No option\n");
    }
    return 0;
}

char *upper(char *str) {
    for (char *p = str; *p; p  ) {
        *p = toupper((unsigned char)*p);
    }
    return str;
}
  • Related