0

たとえば、ポインタが「こんにちは、お元気ですか?」という文字の配列を指している場合です。そして、Helloを指すポインタだけが必要です。私はcharポインターを渡しており、それをcoutすると、配列全体が読み取られます。''に当たると中断するforループを使用してサイズを縮小しようとしています。しかし、私はそれを理解する運がありません。何か案は?

const char *infile(char * file )
{
    cout<<file<<endl;  //this prints out the entire array
    int j;
    for(j=0;j<500; j++)
    {
        if(file[j]==' ')
           break;
    }
    strncpy(file, file,  j);
    cout<<file<<endl;  //how to get this to print out only the first word
}
4

11 に答える 11

2

strncpy()jソース文字列の最初のバイトにヌルターミネータがない場合は、ヌルターミネータを追加しません。そしてあなたの場合、ありません。

私はあなたがしたいことは手動で最初のスペースを\0:に変更することだと思います

for (j = 0; j < 500; j++) {
  if (file[j] == ' ') {
    file[j] = '\0';
    break;
  }
}
于 2012-04-16T19:37:19.057 に答える
2

まず、strtokを避けます(ほとんどの場合、疫病のように)。これは不快ですが、Cでは正当化される場合があります。C++で使用することの正当化と呼ぶものはまだわかりません。

次に、これを処理する最も簡単な方法(C ++を使用している場合)は、文字列ストリームを使用することです。

void infile(char const *file) 
{
    std::strinstream buffer(file);
    std::string word;
    buffer >> word;
    std::cout << word;
}

別の可能性は、std :: string:に組み込まれている関数のいくつかを使用することです。

void infile(char const *file) {
    std::string f(file);
    std::cout << std::string(f, 0, f.find(" "));
}

...これについて考えると、おそらくstringstreamバージョンよりも少し単純です。

于 2012-04-16T19:39:13.607 に答える
1

ポインタは実際には単一のオブジェクトchar*を指しているだけです。charそのオブジェクトが文字列の最初の(または任意の)要素である場合は、ポインタ演算を使用して、その文字列の他の要素にアクセスできます。これは、文字列(C ++スタイルのstd::stringオブジェクトではなくCスタイルの文字列)の一般的な方法です。アクセスしました。

(Cスタイルの)文字列は、ヌル文字(' \0')で終了する文字のシーケンスです。('\0'ターミネータの後は文字列の一部ではありません。)したがって、文字列"foo bar"は次の一連の文字で構成されます。

{ 'f', 'o', 'o', ' ', 'b', 'a', 'r', '\0' }

文字列を"foo bar"から単にに変更する場合"foo"、それを行う1つの方法は、スペース文字をヌル文字に置き換えることです。

{ 'f', 'o', 'o', '\0', ... }

これ...は構文の一部ではありません。まだ存在しているが(、、、)、文字列の一部ではなくなった文字'b''a'表し'r'ます'\0'

std::stringC ++を使用しているので、おそらく;を使用したほうがはるかに良いでしょう。これははるかに強力で柔軟性があり、ターミネータ、メモリ割り当て、およびその他の詳細について心配する必要がありません。(もちろん、この演習の目的がCスタイルの文字列のしくみを学ぶことでない限り。)

これにより、が指す文字列が変更されfileその変更が呼び出し元に表示されることに注意してください。文字列のローカルコピーを作成することで、これを回避できます(これには、スペースを割り当て、後でそのスペースを解放する必要があります)。繰り返しstd::stringますが、この種のことははるかに簡単になります。

最後に、これ:

strncpy(file, file,  j);

いくつかのレベルで悪いです。strncpy()このように送信元と宛先が重複している場合の呼び出しの動作は未定義です。文字通り何でも起こり得ます。またstrncpy()、宛先に適切なNULターミネータを提供する必要はありません。ある意味でstrncpy()は、実際には文字列関数ではありません。存在しないふりをしたほうがいいでしょう。

トピックに関する私の暴言を参照してください

于 2012-04-16T19:49:03.893 に答える
0

char *が指すスペースをmallocを使用して割り当てた場合、reallocを使用してサイズを変更できます。

char * pzFile = malloc(sizeof("Hello how are you?" + 1));
strcpy(pzFile, "Hello how are you?");
realloc(pzFile, 6);
pzFile[6] = '\0';

nullポインタを設定しない場合、文字列を使用すると問題が発生する可能性があることに注意してください。

文字列を短くしようとした場合は、ヌルターミネータを位置6に設定するだけです。割り当てられたスペースは必要以上に大きくなりますが、短くなければ問題ありません。

ほとんどの場合、文字列をスペースまでコピーすることを強くお勧めします。

char * pzInput = malloc(sizeof("Hello how are you?" + 1));
strcpy(pzInput, "Hello how are you?");
char * pzBuffer = malloc(BUFFER_SIZE);

char * pzSrc = pzInput;
char * pzDst = pzBuffer;
while (*pzSrc && ' ' != *pzSrc)
  *(pzDst++) = *(pzSrc++);
*pzDst = '\0';

これはまた、後で使用するために文字列の残りの部分を指すpzSrcで終わります!

于 2012-04-16T19:56:36.943 に答える
0

これは、ポインタのサイズとは何の関係もありません。ポインタは、特定のタイプに対して常に同じサイズになります。

Strtokが最善の解決策かもしれません(strtokを使用するこのコードは、スペース、「、」、ドット、または「-」に出会うたびに文字列をサブ文字列に分割します。

char str[] ="- This, a sample string.";
  char * pch;
  printf ("Splitting string \"%s\" into tokens:\n",str);
  pch = strtok (str," ,.-");
  while (pch != NULL)
  {
    printf ("%s\n",pch);
    pch = strtok (NULL, " ,.-");
  }

出典:CPP STRTOK

于 2012-04-16T19:33:58.973 に答える
0

これを行うのははるかに簡単です

 if(file[j]==' ') {
   file[j] = 0;
   break;
   ..

  // strncpy(file, file,  j);
于 2012-04-16T19:35:06.387 に答える
0

使用strtokすると、あなたの生活がはるかに楽になるかもしれません。
''を区切り文字として文字列を分割し、から取得した最初の要素を出力しますstrtok

于 2012-04-16T19:35:19.193 に答える
0

'strtok'を使用します。例:http ://www.cplusplus.com/reference/clibrary/cstring/strtok/を参照してください。

于 2012-04-16T19:35:33.187 に答える
0

あなたが求めているのが「このポインタが指すメモリブロックのサイズを動的に変更できますか」という場合は、実際にはそうではありません。(目的のサイズの新しいブロックを作成してから、バイトをコピーしたり、最初のブロックを削除したりする必要があります。)

「最初の単語を印刷する」だけの場合は、スペースの位置にある文字を0に設定します。次に、file *ポインターを出力すると、最初の単語(\ 0までのすべて)が取得されます。 。)( nullで終了する文字列を読んで、それがそのように機能する理由の詳細を確認してください。)

しかし、これはすべて、あなたが解決しようとしている問題を実証するための例であるあなたがしていることのどれだけに依存します。本当に「文字列を分割する」場合は、少なくともstrtokの使用を検討する必要があります。

于 2012-04-16T19:39:18.837 に答える
0

一度に各文字を出力し、スペースにヒットしたら中断してみませんか。

const char *infile(char * file )
{
  cout<<file<<endl;  //this prints out the entire array
  int j;

  for(j=0;j<500; j++)
  {
    if(file[j]==' ')
       break;
    cout<<file[j];
  }

  cout<<endl;
}
于 2012-04-16T19:39:23.540 に答える
0
std::copy(file, std::find(file, file+500, ' '),
          std::ostream_iterator<char>(std::cout, ""));
于 2012-04-16T22:17:02.693 に答える