どのようにして正しい番号が得られないのでしょうか? SSCCE に埋め込まれたコードを次に示します ( Short, Self-Contained, Correct Example )。
#include <string.h>
#include <stdio.h>
extern int conta_coords(char *str);
int conta_coords(char *args) {
char *pal;
int k=0;
pal = strtok (args," ");
while (pal != NULL)
{
k++;
pal =strtok (NULL," ");
}
return k;
}
int main(void)
{
char data[] = "1 23 456 7890 12345";
printf("Data: %s\n", data);
printf("Number: %d\n", conta_coords(data));
printf("Data split: %s\n", data);
return 0;
}
出力:
$ ./cntnum
Data: 1 23 456 7890 12345
Number: 5
Data split: 1
$
それは私には正しいように見えます。ただし、元の文字列はバラバラに切断されていることに注意してください。また、読み取り専用の文字列 (文字列リテラル) を渡した場合、strtok()
動作するデータを変更するため、異なる結果が得られた可能性がありますが、文字列リテラルは常に変更可能であるとは限りません (また、試してみるとコア ダンプが発生する可能性があります)。変更する必要があります)。例えば:
printf("Number: %d\n", conta_coords(" 1 23 45 67 99 "));
これにより、「バス エラー」が発生します (無効になっていない場合は、コア ダンプが発生します)。
strspn()
これは、非常に過小評価されている C89 標準関数andを使用して、検索された文字列をまったく変更せずに、定数文字列で機能する代替実装ですstrcspn()
。
#include <string.h>
#include <stdio.h>
extern int conta_coords(const char *str);
int conta_coords(const char *str)
{
const char digits[] = "0123456789";
const char *ptr = str;
int k = 0;
int n = strcspn(ptr, digits);
while (ptr[n] != '\0')
{
ptr += n;
n = strspn(ptr, digits);
if (n > 0)
k++;
ptr += n;
n = strcspn(ptr, digits);
}
return k;
}
int main(void)
{
char data[] = "1 23 456 7890 12345";
printf("Data: %s\n", data);
printf("Number: %d\n", conta_coords(data));
printf("Data unsplit: %s\n", data);
printf("Number: %d\n", conta_coords(" 1 23 45 67 99 "));
return 0;
}
出力:
Data: 1 23 456 7890 12345
Number: 5
Data unsplit: 1 23 456 7890 12345
Number: 5
これに対する 1 つの正当な批判は、整数が空白で区切られていることを要求していないということです (したがって、それをより正確に特徴付けるには、「1 つ以上の連続した数字 (1 つ以上の非数字で区切られている) のシーケンスの数を数えます)」です。指定された文字列に表示されます')。しかし、元のコードも同様の理由で批判される可能性があります。指定された文字列に出現する、1 つまたは複数の空白で区切られた連続した非空白のシーケンスの数をカウントします。実装を改良することはできますが、誤った形式のデータをどのように処理し、問題を報告するかに注意してください。