简体   繁体   中英

Argv doesnt work with char pointer on terminal

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;
}

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;
}
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;
} 

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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM