2016-07-17 7 views
0
static char DEFAULT_DELIMITER = ','; 
char *calculator_retrieveFirstToken(char *numbers, const char * delimiters) { 
    //if (delimiters[strlen(delimiters)-1] == DEFAULT_DELIMITER) 
    if (delimiters[1] == DEFAULT_DELIMITER) { 
     return strtok(numbers, delimiters); 
    } 
    else { 
     char linefeed = '\n'; 
     strtok(numbers, &linefeed); 
     return strtok(NULL, delimiters); 
    } 
} 

char calculator_findDelimiter(const char *numbers) { 
    char delimiter = DEFAULT_DELIMITER; 
    if (strlen(numbers) >= 4 
     && numbers[0] == '/' 
     && numbers[1] == '/') { 
     delimiter = numbers[2]; 
    } 
    return delimiter; 
} 

double calculator_add(char *numbers) { 
    char delimiters[] = "\n"; 
    char *token = NULL; 

    char mainDelimiter = calculator_findDelimiter(numbers); 
    strcat(delimiters, &mainDelimiter); 
    token = calculator_retrieveFirstToken(numbers, delimiters); 
    return calculator_addEveryToken(token, delimiters); 
} 

calculator_retrieveFirstToken関数にデバッグすると、最も奇妙なことが起こります。数字入力の関数がconst charとして送信しているものを受け取っていません。*

例: "私はに行くとき\ nを、 '

"

mainDelimiterがに等しい "" strcatの呼び出しの後

::区切り文字に等しいです'何かが私のstrcatの呼び出しと間違っている....私はそれが動作するとしているかを理解していない

「nは\、\ n」は :calculator_retrieveFirstTokenは、区切り文字のparamはと同等の機能しますか?

ここchar変数へのポインタをchar配列(すなわち、列)へのポインタを取り、ないstrcat

#include "calculator_kata.h" 
#include <assert.h> 
#include <string.h> 
#include <math.h> 
#include <stdbool.h> 

static char numbers[50]; 

static bool equals(const double expected, const double received) 
{ 
    double epsilon = 1e-7; 
    return fabs(received - expected) < epsilon; 
} 

static void test_addEmptyString_shouldReturnZero() 
{ 
    strcpy(numbers, ""); 
    const double sum = calculator_add(numbers); 
    assert(equals(0, sum)); 
} 

static void test_addOneNumber_shouldReturnThisNumber() 
{ 
    strcpy(numbers, "42"); 
    const double sum = calculator_add(numbers); 
    assert(equals(42, sum)); 
} 

static void test_addTwoNumbers_shouldReturnTheSum() 
{ 
    const double TWENTY_ONE = 9+10; 
    strcpy(numbers, "9,10"); 

    const double sum = calculator_add(numbers); 

    assert(equals(TWENTY_ONE, sum)); 
} 

static void test_addAnyQtyOfNumbers_shouldReturnTheSum() 
{ 
    strcpy(numbers, "1,2,3,4,5"); 
    const double sum = calculator_add(numbers); 
    assert(equals(15, sum)); 
} 

static void test_inputWithNewLines_insteadOfCommas_shouldStillBeParsed() 
{ 
    strcpy(numbers, "1\n2,3"); 
    const double sum = calculator_add(numbers); 
    assert(equals(6, sum)); 
} 

static void test_inputWithMultipleCommasBetweenNumbers_shouldReturnTheSum() 
{ 
    strcpy(numbers, "1\n,2,,,,,,,3"); 
    const double sum = calculator_add(numbers); 
    assert(equals(6, sum)); 
} 

static void test_inputWithCustomDelimiter_shouldChangeDelimiter() 
{ 
    strcpy(numbers, "//;\n1;2"); 
    const double sum = calculator_add(numbers); 
    assert(equals(3, sum)); 
} 

int main() 
{ 
    test_addEmptyString_shouldReturnZero(); 
    test_addOneNumber_shouldReturnThisNumber(); 
    test_addTwoNumbers_shouldReturnTheSum(); 
    test_addAnyQtyOfNumbers_shouldReturnTheSum(); 
    test_inputWithNewLines_insteadOfCommas_shouldStillBeParsed(); 
    test_inputWithMultipleCommasBetweenNumbers_shouldReturnTheSum(); 
    test_inputWithCustomDelimiter_shouldChangeDelimiter(); 
    return 0; 
} 
+0

問題の原因となる入力/パラメータの例を見て、あなたのメインの外観を表示できますか? –

+0

@RetiredNinjaメイン全体を追加しました –

+0

'strtok(numbers、&linefeed)'が間違っています。 'delim'パラメータはヌルで終了する文字列へのポインタです* NOT * charへのポインタ*(' man 3 strtok'を参照)(**注意:* * manページ*の記述では* string *の使用「デリム」の) –

答えて

0

strtokだと。つまり、文字列ターミネータ('\0')が必要です。

また、calculator_addには、に十分なスペースが定義されていないため、strcatは未定義の動作を引き起こします。

私はあなたのソースにバグと注釈を付けて修正しました。可能であれば、私はしました:// NOTE/BUG: ... #if 0 /* original code */ #else /* fixed code */ #endif

static char DEFAULT_DELIMITER = ','; 
char *calculator_retrieveFirstToken(char *numbers, const char * delimiters) { 
    //if (delimiters[strlen(delimiters)-1] == DEFAULT_DELIMITER) 
    if (delimiters[1] == DEFAULT_DELIMITER) { 
     return strtok(numbers, delimiters); 
    } 
    else { 
     // NOTE/BUG: this is incorrect -- you must pass a string pointer _not_ 
     // the address of a [single] character 
#if 0 
     char linefeed = '\n'; 
     strtok(numbers, &linefeed); 
#else 
     char *linefeed = "\n"; 
     strtok(numbers, linefeed); 
#endif 

     return strtok(NULL, delimiters); 
    } 
} 

char calculator_findDelimiter(const char *numbers) { 
    char delimiter = DEFAULT_DELIMITER; 
    if (strlen(numbers) >= 4 
     && numbers[0] == '/' 
     && numbers[1] == '/') { 
     delimiter = numbers[2]; 
    } 
    return delimiter; 
} 

double calculator_add(char *numbers) { 
    // NOTE/BUG: this defines only enough space for a single character and the 
    // '\0' so when it is concatenated to, it is undefined behavior [you're 
    // running past the end of the string] 
#if 0 
    char delimiters[] = "\n"; 
#else 
    char delimiters[4] = "\n"; 
#endif 
    char *token = NULL; 

    // NOTE/BUG: this repeats the same mistake with the strtok above 
#if 0 
    char mainDelimiter = calculator_findDelimiter(numbers); 
    strcat(delimiters, &mainDelimiter); 
#endif 

    // NOTE: either of these will fix the strcat 
#if 0 
    char mainDelimiter = calculator_findDelimiter(numbers); 
    char temp[2]; 
    temp[0] = mainDelimiter; 
    temp[1] = 0; 
    strcat(delimiters, temp); 
#else 
    delimiters[1] = calculator_findDelimiter(numbers); 
    delimiters[2] = 0; 
#endif 

    token = calculator_retrieveFirstToken(numbers, delimiters); 
    return calculator_addEveryToken(token, delimiters); 
} 
関連する問題