2017-10-05 10 views
0

で予期しない出力を取得する。..は、以下の基準でこのメソッドを書くエラー

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 

なぜこのエラーoccuringはありますか?どうすれば最初のエラーメッセージが表示されなくなり、入力された文字列の途中に数字がある場合にプログラムが中断しないのですか?

+0

このプログラムは、デバッガに最適です。 –

+0

正直なところ、デバッガを正しく使う方法がわからず、sshとvimを使ってリモートマシンを使用しています – sgerbhctim

+0

文字列が終了すると通常通り終了するパスが必要です。 – BLUEPIXY

答えて

-1

最初のケース:

abbbbあなたが割り当てられているバッファ内の文字列a1b4を準備する機能encrypt()を、(sprintf()がメモリに起こり、何がコンソールに表示されることはありません)を呼び出します。

文字列はヌルターミネータで終了します。ループがこの時点で到着すると、tmpはnullになります。残念ながら、これにより即時のメッセージerrorがコンソールに表示されます。関数が戻り、バッファ内の結果が出力されます。

第二の場合:

a23rまず、encrypt()は、入力文字列を解析を開始し、有効な文字の出力文字列を作成します。これにより、a1が生成されます。 2回目の反復では、数字'2'が発生し、isdigit(tmp)が真となります。再び、errorという出力がコンソールに出力されます。関数はそれから戻ります。しかし、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()に出力を制御することができます:

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を前提としています。この条件が満たされない場合は、整数のオーバーフローが発生し、割り当てが不十分でメモリが破損する可能性があります。

関連する問題