使用以下标准编写此方法..
INPUT:aabbb 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
为什么会出现此错误?我怎样才能使第一个错误信息停止出现,为什么程序在输入字符串中间有数字时不会中断?
答案 0 :(得分:-1)
第一种情况:abbbb
您调用函数encrypt()
,它在您已分配的缓冲区中准备字符串a1b4
(sprintf()
在内存中发生,并且不会导致在控制台上显示任何内容)。
字符串以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
。如果不满足此条件,您可能会遇到整数溢出,导致分配不足和内存损坏。