dポイントプレゼントキャンペーン実施中!

Cでやり方がわからないことがあるのでご質問があります。

文字型配列、例えばchar buf[128]にfgetsなどで、文字列を格納したとします(例えば"abc defghi ")。
この場合、最後に続く空白がその後の作業で邪魔なので新しい文字型配列もしくはポインタに、2つ以上空白が続いた場合は、最後の文字までで、以下の空白は切り捨てた状態("abc defghi")で格納したいのですが方法が思い浮かばず困っています。

よい方法があればお教えください。
よろしくお願いします。

A 回答 (6件)

バグってましたね、わたし^^; こうですね。


=====
#include <ctype.h>

void end_trim(char *s)
{
char *p = s;
if (!*p) return;
while (*p) ++p;
--p;
while (s < p && isspace(*p)) --p;
if (s == p && isspace(*p)) *p = '\0';
else *++p = '\0';
}
    • good
    • 1

あぁ。

。あと、strrchr() は、たぶん、downboy さんが必要なものではないでしょう。strrchr() は、末尾から指定された文字を探すだけですから、非空白文字の間に入っている空白も探しますのからね。末尾から空白が続いているかどうかは判別できません(末尾の空白の連かどうかを調べようと思えば、ポインタの比較するのでしょうが、それをやるなら、自分でループを書くのよりごちゃごちゃするでしょう)。
    • good
    • 0

「2つ以上空白…」のところの意味がよくわからないし、空白というのがスペースだけの意味なのか、isspace() が true になるものという意味なのかわかりませんが。

。とりあえず、文字列の末尾の空白類を省くというようなのは、以下の end_trim() のような感じになると思いますよ。
====
#include <ctype.h>

void end_trim(char *s)
{
char *p = s;
while (*p) ++p;
--p;
while (s < p && isspace(*p)) --p;
*p = '\0';
}

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

int main()
{
char a[] = "akak dkj kdfl ";
printf("\"%s\"\n", a);
end_trim(a);
printf("\"%s\"\n", a);
a[0] = '\0';
printf("\"%s\"\n", a);
end_trim(a);
printf("\"%s\"\n", a);
strcpy(a, " ");
printf("\"%s\"\n", a);
end_trim(a);
printf("\"%s\"\n", a);
}
==== テスト結果
% ./a.out
"akak dkj kdfl "
"akak dkj kdf"
""
""
" "
""
    • good
    • 0

★sakusaker7へ。


>自分で作るまでもなくそれがないライブラリしかない
>コンパイラを探す方が大変なのでは?
今、調べたら ANSI-C から strrchr() 関数はありましたね。
昔、strrchr を自作した記憶があり(ANSI-C)は無かったと思い込んでしまいました。
strdup、strrev はマクロソフト社の独自関数で strrchr などもそうなのかと思いました。

もしかしたら C 言語のお勉強として文字列の関数を自分でも実装していた頃の記憶で
ANSI-C には無かったという思い込みをしていたようです。
ご指摘有り難うございました。

質問者さんへ。
・strrchr() 関数に関しては自作する必要は無いみたいです。
 ただマルチバイト文字(漢字文字)の第2文字と同じ文字を検索するときは注意して下さい。
 今回は空白文字なので特に問題はないですけど。
・以上。

参考URL:http://always-pg.com/c/runtime_rd/string/strrchr …
    • good
    • 0

> あと strchr() に似せた strrchr() 関数を作成しておくと便利です。



自分で作るまでもなくそれがないライブラリしかない
コンパイラを探す方が大変なのでは?

BohYoh.com【C言語講座】標準ライブラリ関数 strrchr
http://www.bohyoh.com/CandCPP/C/Library/strrchr. …

sが指す文字列の中に最も末尾側に出現する(char型に変換した)cを探す。cは文字列の終端を示すナル文字でもよい。
探し出した文字へのポインタを返す。文字がなければ空ポインタを返す。
    • good
    • 0

★末尾空白の削除ですよね。


・仕組みは
 (1)fgets() 関数で取得した文字列 buf の末尾にポインタを移動します。
 (2)末尾ポインタを buf の先頭に向けて移動しながら
  空白文字なら \0 を書き込む
  空白以外の文字(英字)が最初に現れたら break で抜ける
 (3)移動ポインタが buf まで来てしまったら全てが空白文字の文字列なので buf の
  先頭に \0 が書き込まれて処理が終了します。
 考え方はこんな感じです。
・別の文字型配列やポインタ領域にコピーする方法もありますが、連続する末尾の空白を
 \0 文字で上書きする方が簡単かもしれない。
 上記以外にもいろいろと方法はあると思います。
 下にサンプルを載せておきます。

サンプル:
// 空白文字の定数
#define SPC ' '

char buf[ 128 ];
char *p;

// 文字列の入力
fgets( buf, sizeof(buf), fp );

// 末尾へポインタを移動
for ( p = buf ; *p != '\0' ; p++ ){
 ;
}
// 末尾の連続する空白を \0 で上書き
for ( p-- ; p >= buf ; p-- ){
 if ( *p == SPC ){
  *p = '\0';
 }
 else{
  break;
 }
}

その他:
・末尾の連続する空白以外を別領域にコピーする場合は最後に現れた空白文字を探して
 そこまでをコピーすれば良いです。
 こちらはご自分で考えてみて下さい。
・あと strchr() に似せた strrchr() 関数を作成しておくと便利です。
 char *strrchr(str,c) 関数は最後に見つかった c のポインタ位置を返す仕様です。
 見つからない場合は NULL ポインタを返すようにします。
 こんな関数を自作して用意しておけばいろいろと便利に今後利用できます。
 これも興味があったらご自分で作ってみて下さい。
・以上。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!