0
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
char *tokenstring = "first,25.5,second,15";
int result, i;
double fp;
char o[10], f[10], s[10], t[10];
void main()
{
   result = sscanf(tokenstring, "%[^','],%[^','],%[^','],%s", o, s, t, f);
   printf("%s\n %s\n %s\n %s\n", o, s, t, f);
   fp = atof(s);
   i  = atoi(f);
   printf("%s\n %lf\n %s\n %d\n", o, fp, t, i);
}

上記のコードは '\t' では機能しません。なぜですか? 私はvc6.0 を使用しています

動作しません

char *tokenstring = "first\t25.5\tsecond\t15";



   result = sscanf(tokenstring, "%[^'\t'],%[^'\t'],%[^'\t'],%s", o, s, t, f);
4

2 に答える 2

3

あなたのフォーマットが一致しているものを見てください:

"%[^'\t'],%[^'\t']
 ^     ^ ^
 \     | \- match a literal comma
  \    |
   \---+- match a sequence not containing tab or ' (single quote), up to the next
          tab or single quite.

したがって、最初の%[..]ものは、入力の最初のタブを含めずにそれまでのすべてに一致し、次に、タブに一致しないコンマと一致しようとするため、失敗します。

最も簡単な修正方法は、文字列内のコンマをスペースに置き換えることです。これにより、空白 (タブを含む) がスキップされます。タブを使用しても同じことができますが、空白をスキップするのではなく、タブを一致させようとしていると人々を混乱させるでしょう:

sscanf(tokenstring, "%[^\t] %[^\t] %[^\t]%s", o, s, t, f);

'また、失敗させたくない場合を除き、マッチでキャラクターを特別に扱いたくない可能性があることに注意してください。

セパレーターに (空白だけでなく) タブだけを使用する場合は、タブ パターンを使用する必要があります。

sscanf(tokenstring, "%[^\t]%*1[\t\]%[^\t]%*1[\t]%[^\t]%s", o, s, t, f);

パターン%*1[\t]は入力内の単一のタブと正確に一致し、どこにも保存されません。

これは、最初の (カンマベースの) scanf で気付いたかもしれない別の問題につながります-- 入力の次の文字が a (または2 番目のケース) の場合、scanf は空文字列のようなパターン%[^,]または一致しません。空の文字列を格納するのではなく、何も (または次のパターンのいずれにも) 一致せずに単純に戻ります。%[^\t],\t

さらに、文字列のいずれかが配列に対して長すぎる場合、オーバーフローしてクラッシュします (またはさらに悪化します)。したがって、scanf%sまたは%[パターンをバッファーに使用するときは常に、バッファー サイズを指定する必要があります。

sscanf(tokenstring, "%9[^,],%9[^,],%9[^,],%9s", o, s, t, f);

入力が長すぎる場合、クラッシュまたは破損する代わりに、sscanf呼び出しはフィールドの最初の 9 文字のみに一致し、フィールドの残りはまだ読み取られていない状態で返されます。

于 2014-04-18T17:34:55.107 に答える
2

コンマを使用してフィールドを区切る場合は,、フォーマット文字列に a を追加してスキップする必要があります。についても同様です\t

#include <math.h>
#include <stdio.h>
#include <stdlib.h>

void test1()
{
   char *tokenstring = "first,25.5,second,15";
   int result, i;
   double fp;
   char o[10], f[10], s[10], t[10];

   // -----------------------------------------------------------
   // make sure you add a , between the string format specifiers
   // -----------------------------------------------------------
   result = sscanf(tokenstring, "%[^,],%[^,],%[^,],%s", o, s, t, f);
   printf("%s\n %s\n %s\n %s\n", o, s, t, f);
   fp = atof(s);
   i  = atoi(f);
   printf("%s\n %lf\n %s\n %d\n", o, fp, t, i);
}

void test2()
{
   char *tokenstring = "first\t25.5\tsecond\t15";
   int result, i;
   double fp;
   char o[10], f[10], s[10], t[10];

   // -----------------------------------------------------------
   // make sure you add a \t between the string format specifiers
   // -----------------------------------------------------------
   result = sscanf(tokenstring, "%[^\t]\t%[^\t]\t%[^\t]\t%s", o, s, t, f);
   printf("%s\n %s\n %s\n %s\n", o, s, t, f);
   fp = atof(s);
   i  = atoi(f);
   printf("%s\n %lf\n %s\n %d\n", o, fp, t, i);
}

void main()
{
   test1();
   test2();
}
于 2014-04-18T17:34:26.083 に答える