5

ポインターと文字列の解析がどのように機能するかを誰かが説明してくれるかどうか疑問に思っていました。ループで次のようなことができることは知っていますが、それがどのように機能するかはまだよくわかりません。

  for (a = str;  * a;  a++) ...

たとえば、文字列から最後の整数を取得しようとしています。次のような文字列がある場合const char *str = "some string here 100 2000";

上記の方法を使用して、最後の整数 (2000) が異なる可能性があることを知って、それを解析して文字列の最後の整数 (2000) を取得するにはどうすればよいでしょうか。

ありがとう

4

5 に答える 5

8

for (a = str; * a; a++) ...

aこれは、逆参照aが暗黙的に false に変換されa、各ステップでインクリメントされるまで、文字列の先頭でポインターを開始することによって機能します。

基本的に、文字列の末尾にある NUL ターミネータ ( \0) に到達するまで配列をウォークします。これは、NUL ターミネータが暗黙的に false に変換されるためです。他の文字はそうではありません。

上記の方法を使用して、最後の整数 (2000) が異なる可能性があることを知って、それを解析して文字列の最後の整数 (2000) を取得するにはどうすればよいでしょうか。

の前の最後のスペースを探し\0、関数を呼び出して残りの文字を整数に変換する必要があります。を参照してくださいstrtol

次のアプローチを検討してください。

  • 文字列の末尾を見つける (そのループを使用)
  • 後方にスペースを検索します。
  • それを使って を呼び出しますstrtol

-

for (a = str; *a; a++);  // Find the end.
while (*a != ' ') a--;   // Move back to the space.
a++;  // Move one past the space.
int result = strtol(a, NULL, 10);

または、最後のトークンの開始を追跡するだけです。

const char* start = str;
for (a = str; *a; a++) {     // Until you hit the end of the string.
  if (*a == ' ') start = a;  // New token, reassign start.
}
int result = strtol(start, NULL, 10);

このバージョンには、文字列にスペースを必要としないという利点があります。

于 2010-06-27T14:57:15.010 に答える
3

たとえば、2 つの状態を持つ単純なステート マシンを実装する必要があります。

#include <ctype.h>

int num = 0; // the final int value will be contained here
int state = 0; // state == 0 == not parsing int, state == 1 == parsing int

for (i = 0; i < strlen(s); ++i)
{
    if (state == 0) // if currently in state 0, i.e. not parsing int
    {
        if (isdigit(s[i])) // if we just found the first digit character of an int
        {
            num = s[i] - '0'; // discard any old int value and start accumulating new value
            state = 1; // we are now in state 1
        }
        // otherwise do nothing and remain in state 0
    }
    else // currently in state 1, i.e. parsing int
    {
        if (isdigit(s[i])) // if this is another digit character
        {
            num = num * 10 + s[i] - '0'; // continue accumulating int
            // remain in state 1...
        }
        else // no longer parsing int
        {
            state = 0; // return to state 0
        }
    }
}
于 2010-06-27T15:01:08.433 に答える
3

これはすでに回答されていることは知っていますが、これまでのすべての回答は、標準 C ライブラリで利用可能なコードを再作成しています。これを利用して使用するものは次のとおりですstrrchr()

#include <string.h>
#include <stdio.h>

int main(void)
{

    const char* input = "some string here 100 2000";
    char* p;
    long l = 0;

    if(p = strrchr(input, ' '))
        l = strtol(p+1, NULL, 10);

    printf("%ld\n", l);

    return 0;
}

出力

2000
于 2010-06-27T21:58:15.997 に答える
0
  for (a = str;  * a;  a++)...

と同等です

  a=str;
  while(*a!='\0') //'\0' is NUL, don't confuse it with NULL which is a macro
  {
      ....
      a++;
  }
于 2010-06-27T14:58:09.233 に答える
-1

あなたが提示したループは、すべての文字を処理するだけです (string は、0 で終わる 1 バイト文字の配列へのポインターです)。解析には、sscanf以上C++の文字列と文字列ストリームを使用する必要があります。

于 2010-06-27T14:56:40.173 に答える