2017-10-05 145 views
0

写该方法用以下标准意想不到输出..掌握错误

INPUT:aa​​bbb OUTPUT:A2B3

INPUT:AB输出:AB(因为它比A1B1短)

INPUT: a23输出:错误(不读取数字)

这是我目前使用的方法。

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 

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

+0

该程序非常适合调试器。 –

+0

老实说,非常令人尴尬的是不知道如何正确使用调试器,并且通过ssh和vim使用远程机器 – sgerbhctim

+0

您需要一个当字符串结束时正常结束的路径。 – BLUEPIXY

回答

-1

第一种情况:abbbb

调用该函数encrypt(),其中准备串a1b4在你分配(sprintf()发生在内存中,不会引起任何被显示在控制台上)的缓冲。

该字符串以空终止符终止。当你的循环到达这一点时,tmp将为空。不幸的是,这会导致在控制台上打印一条即时消息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。如果不满足此条件,则可能会遇到整数溢出,导致分配不足和内存损坏。