Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 获取错误的意外输出_C - Fatal编程技术网

C 获取错误的意外输出

C 获取错误的意外输出,c,C,使用以下条件编写此方法 输入:aabbb输出:a2b3 输入:ab输出:ab,因为它比a1b1短 输入:a23输出:错误不读取数字 这是我目前的方法 void encrypt(char* crypt, const char* source) { while (1) { char tmp = *source; if (!tmp) { *crypt = 0; printf("error\n");

使用以下条件编写此方法

输入:aabbb输出:a2b3

输入:ab输出:ab,因为它比a1b1短

输入: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
为什么会发生这种错误?如何使第一个错误消息停止,为什么在输入字符串中间有数字时程序不中断? 第一例:abbb

调用函数encrypt,它在内存中准备分配给sprintf的缓冲区中的字符串a1b4,并且不会在控制台上显示任何内容

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

第二例:a23r

首先,encrypt开始解析输入字符串,并为有效字母创建输出字符串。这就产生了a1。在第二次迭代中,它遇到数字“2”,这导致isdigittmp为true。同样,会立即将错误输出到控制台。然后该函数返回。但是a1已经在缓冲区中,所以它也被输出到控制台

如何把事情安排得井井有条

更改函数,以便将错误情况通知调用方。例如,返回0表示ok,另一个值表示发生错误

#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中的输出:

最后一句话


注意:mallocstrlensource*2+1假设strlensource此程序非常适合调试器。老实说,非常尴尬的是,我不知道如何正确使用调试器,我正在通过ssh和VIM使用远程计算机。您需要一个在字符串结束时正常结束的路径。您也可以远程运行调试器。把它当作一个学习如何使用它的机会。或者,您也可以设置本地环境。为什么第一个错误fprinf是错误?这看起来是正常的退出条件。每次点击字符数组终止符null时都会出现这种情况。
int err = encrypt(crypt, source);
if (!err)
    printf("%s\n", crypt);
else printf ("Error (code %d)\n", err);