获得错误

时间:2017-10-05 18:24:48

标签: c

使用以下标准编写此方法..

INPUT:aa​​bbb OUTPUT:a2b3

INPUT:ab OUTPUT:ab(因为它短于a1b1)

INPUT:a23 OUTPUT:错误(不读数字)

这是我目前的方法。

void encrypt(char* crypt, const char* source) {


    while (1) {

        char tmp = *source;

        if (!tmp) {
            *crypt = 0;
            printf("error\n");
            return;
        }

        size_t count = 1;
        while (*(++source) == tmp){
            if(isdigit(tmp)){
                printf("error\n");
                return;
            }
            ++count;
        }
        *(crypt++) = tmp;
        crypt += sprintf(crypt, "%zu", count);
    }

}

int main(int argc, char **argv) {

   if (argc != 2) {
      fprintf(stderr, "error\n");
      return 1;
   }

   const char* source = argv[1];

   char* crypt = malloc(strlen(source)*2+1);

   encrypt(crypt, source);
   printf("%s\n", crypt);
//   free(crypt);
   return 0;

}

非常奇怪,每次运行时,我都会得到输出:

./prog abbbb
error
a1b4

./prog a23r
error
a1

为什么会出现此错误?我怎样才能使第一个错误信息停止出现,为什么程序在输入字符串中间有数字时不会中断?

1 个答案:

答案 0 :(得分:-1)

第一种情况:abbbb

您调用函数encrypt(),它在您已分配的缓冲区中准备字符串a1b4sprintf()在内存中发生,并且不会导致在控制台上显示任何内容)。

字符串以null终止符终止。当你的循环到达此点时,tmp将为null。不幸的是,这会导致在控制台上打印出即时消息error。然后函数返回,并打印缓冲区中的结果。

第二种情况:a23r

首先,encrypt()开始解析输入字符串并为有效字母创建输出字符串。这会产生a1。在第二次迭代中,它遇到数字'2',这导致isdigit(tmp)为真。同样,控制台立即输出error。然后该函数返回。但a1已经在缓冲区中,因此它也会输出到控制台。

如何按正确的顺序获取内容?

更改您的功能,以便通知来电者错误情况。例如,返回0表示正常,另一个值表示发生错误。

#define ERR_EMPTY   1         /* error: empty string */
#define ERR_INVALID 2         /* error: invalid character */

int encrypt(char* crypt, const char* source) {
    int rc = 0;                   // return= 0;  

    if (!*source)                 // if input string is empty 
        rc = ERR_EMPTY; 
    else {      
        while (*source) {             // loop while the char is not zero
            char tmp = *source;
                                      // (don't show a error at the null terminator)
            if(isdigit(tmp)){
                rc = ERR_INVALID;
                break;
            }
            size_t count = 1;
            while (*(++source) == tmp){
                ++count;
            }
            *(crypt++) = tmp;
            crypt += sprintf(crypt, "%zu", count);
        }
    }
    *crypt = 0;   // prevent risks:  in every case put a null terminator 
    return (rc); 
}

通过此更改,您可以更好地控制main()中的输出:

int err = encrypt(crypt, source);
if (!err)
    printf("%s\n", crypt);
else printf ("Error (code %d)\n", err); 

最后评论

注意:malloc(strlen(source)*2+1)假定为strlen(source)<(SIZE_MAX-1)/2。如果不满足此条件,您可能会遇到整数溢出,导致分配不足和内存损坏。