简体   繁体   English

Argv 不适用于终端上的 char 指针

[英]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.我想编写一个程序,当我在终端上编写prog.exe -u word时,会将word转换为大写,否则跳过该过程。 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指针output声明为

char * output;

is uninitialized and has an indeterminate value.未初始化并且具有不确定的值。

So using it in the function upper invokes undefined behavior.所以在 function upper使用它会调用未定义的行为。

Instead of the pointer you should use a character array large enough to store the passed string to the function.您应该使用足够大的字符数组来代替指针,以将传递的字符串存储到 function。

If the compiler supports variable length arrays then you can write如果编译器支持可变长度 arrays 那么你可以写

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

And this if statement而这个 if 语句

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

will be more readable than this if statement将比这个 if 语句更具可读性

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在 function 中,至少在 if 语句中使用字符符号'a''z'而不是幻数97122会更好

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> .尽管使用在 header <ctype.h>中声明的标准 function islowertoupper会更好。

The function can be declared and defined the following way function可以通过以下方式声明和定义

#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 .该程序具有未定义的行为,因为您尝试将转换后的字符串存储到未初始化的指针output

Note that using hard coded constants such as 97 , 122 and 32 is both confusing and non portable to non-ASCII environments.请注意,使用诸如9712232之类的硬编码常量既令人困惑,也无法移植到非 ASCII 环境中。 You should use the macros and functions from <ctype.h> for readability and portability.您应该使用<ctype.h>中的宏和函数来提高可读性和可移植性。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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