
表題にあるとおり間の文字列をどうやって取得するべきかと悩んでいます・・
abcdefghijklmn・・・
となっているとき
bとe、aとkなど間の間隔が不定なときはどのようにして文字列を取得したらよいのでしょうか?
最初の2文字は与えられているとして考えています。
インターネットのURLで言うなら/から/までの間の文字列と言うことになります。
今私が考えているのは
strchrで位置のアドレスを取得してそこからfor文かwhile文で指定の2文字目が出るまでまわすのかなぁ・・と思っています。
ですが具体的にどのような感じに書けばいいのかがわかりません。どなたかご教授ください。
No.1ベストアンサー
- 回答日時:
2文字の間でいいのなら strchr() を2回使えばいいと思います。
例
char *p, *q;
if ((p = strchr(s, 'b')) != NULL) {
if ((q = strchr(p + 1, 'e')) != NULL) {
/* p + 1 ~ q - 1 が 'b' から 'e' の間の文字列 */
size_t len = q - p - 1; /* これがバイト数 */
printf("%-.*s\n", len, p + 1); /* 出力 */
}
}
複数の文字の中のいずれかの文字が出現した所で区切りたいなら strpbrk() か strtok() を使えばいいと思います。
No.10
- 回答日時:
>この場合一回の検索で処理が終了してしまいますので、ファイル全体で検索するにはどうしたらよいのでしょうか?
メモリが湯水のように使える昨今、ファイルのサイズで全部読み込んで処理しても良かろうとかいうのも1つの考えですが、
cut でも処理する分の作業メモリを確保しているので、それはちょっとって感じですね。
なので、ファイルからマッチした、とかフラグを立てて、処理するんですかね。
マッチさせる範囲が、1行を基準として、行をまたがないということであれば、1行分読み込んで同様の処理をすればいいですね。
その場合cut のようなものでも処理できると思います。
それで、その場合繰り返しについてですが、
既に、色々回答がでているように、前回マッチした次から検索させればいいですね。
例えば、cut は、取り出した文字列(buff)へのポインタを返すようになっていますけど、取り出す文字列の先頭位置あるいは、後尾の位置を返すようにすれば、簡単に繰り返し使えるようになると思います。
その場合、
stxxxxstxxxxen
のような文字列でst~en を取り出す場合
1回目:xxxxstxxxx
2回目:xxxx
のような動作になるのか、それとも1回目のen の後からマッチングを始めるのか仕様を決めてやらないといけませんね。
こうした処理は、いわゆる正規表現のマッチングに似た処理と言えるので、複雑になるようだったら、ライブラリ(既に誰かが作ったモノregex.c で検索するといいかも)を使うと良いかも知れません。
あるいは、プログラムを作ることが問題なのではなくて、
処理することが問題なのであれば、そのような正規表現を使えるツールがたくさんありますので、そういうものに処理させて、結果をプログラムで扱うというような方針もありかと思います。
>複数該当する文字がある場合どうしたら良いのでしょうか?
例えば、
ab 又は、AB から始まって、yz または、YZ で終わるというようなことでしょうか?
組み合わせが増えるだけで(といっても爆発的に増える)基本的には、同じことですが、配列で候補を渡してやって組み合わせて調べるというようなことになるんじゃないでしょうか
やはり、より条件が汎用的&難しくなるようなら、正規表現ライブラリを使うのがよかろうと思います。
この回答への補足
>仕様を決めてやらないといけませんね。
私が求めている仕様は1回目:xxxxstxxxx2回目:xxxxでは無く2回目はenの後から始まるようにすると言うことです。処理することが問題ではないです・・基本的に勉強です。やはり気になってしまう・・理解できないと不快感が現れてしまいます・・。あからさまに不快感ではなく、もやもやとした感じです。>複数該当・・という質問には上記の回答で答えてもらっています。ほんと質問がややこしくてすいません・・
No.9
- 回答日時:
#8ですが
s=strstr(wk, ss); if(s==NULL){ free(wk); return NULL;}
e=strstr(c, es); if(e==NULL){ free(wk); return NULL; }
に修正してください。
ありがとうございます。
関数の処理は大体理解できました。この場合一回の検索で処理が終了してしまいますので、ファイル全体で検索するにはどうしたらよいのでしょうか?
あと、このように回答できるのは経験なのでしょうか?
C言語に関する良書または読むべき参考書等あればよろしくお願いします。趣旨が変わってしまいますが。
複数該当する文字がある場合どうしたら良いのでしょうか?cut関数におそらく次の文字へ移行するためのコードを追記しなくてはいけないと思うのですが・・。
No.8
- 回答日時:
//文字列版
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char *cut(const char *str, const char *ss, const char *es, char *buff){
/* str の ss の次から es の前までの文字列をbuff に切り出す */
char *wk, *s, *e, *c;
wk=strdup(str); if(wk==NULL)return NULL;
s=strstr(wk, ss); if(s==NULL) return NULL;
c=s+strlen(ss);
e=strstr(c, es); if(e==NULL) return NULL;
*e='\0';
strcpy(buff, c);
free(wk);
return buff;
}
int main(void){
const char text[]="abcdefghijklmn";
const char url[]="http://www.sample.ne.jp/";
char buff[32];
printf("abc~mn:%s\n", cut(text, "abc", "mn", buff));
printf("//~/:%s\n", cut(url , "//", "/", buff));
return 0;
}
No.7
- 回答日時:
>やりたい処理は文字列と文字列の間です・・scからでは無くscの後からecの前までということです・・紛らわしくて・・本当にすいません・・
いえいえ、
なんちゅーか、書いてあることそのままじゃなくて、
好きにすればいいんですよ♪
No.6
- 回答日時:
これが使えるんじゃないでしょうか?
確かに使えそうです。
ですが、私の完全な経験不足で・・と言うのもイメージ力に欠けるのかもしれませんが、具体的にソースプログラムを書いてもらってそれを見ながらどういう処理を行っているのか説明してもらいたいです。
極端に言えば、質問したプログラムを作ってもらって
逐一説明ってことになります。
申し訳ありません。理解力が乏しくデバッカで追いながら理解している形です・・

No.5
- 回答日時:
区切りは文字か、文字列か、
見つからないときどうするか、など
#4さんと同じ感想(仕様があいまい)。
でも面白そうなのでちょっと作ってみました。
C/C++混在してます。ごめん
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int usage(void){
puts("need 3 args.\nUSAGE:");
puts(" 1st. source string.");
puts(" 2nd. beforehand charactor.");
puts(" 3rd. afterhand charactor.");
return EXIT_FAILURE;
}
char* get_sandwiched_str(const char* src, int before, int after){
char* find_before = strchr(src, before);
char* find_after = find_before? strrchr(find_before + 1, after): NULL;
if (!find_before || !find_after) return NULL;
// if ( find_before >= find_after) return NULL;
*find_after = 0x00;
return find_before + 1;
}
int main(int argc, char** argv){
if (argc != 4) return usage();
char* src = new char[strlen(*++argv) + 1];
strcpy(src, *argv);
int before = *(*++argv);
int after = *(*++argv);
char* result = get_sandwiched_str(src, before, after);
if (result)
printf("'%s'\n", result);
else
puts("missing.");
delete[] src;
return 0;
}
No.4
- 回答日時:
始まりと終わりが、文字列から文字列なのか、文字から文字なのか、質問があいまいですが、strchr()を使うとありますので、文字から文字と解釈します。
-- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< --
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
char *prog;
void
usage(void)
{
fprintf(stderr, "Usage: %s strings 2letters\n", prog);
exit(EINVAL);
}
int
main(int argc, char *argv[])
{
char *p, *q, *r;
prog = argv[0];
if (argc < 3 || strlen(argv[2]) != 2) {
usage();
}
if ((p = strchr(argv[1], argv[2][0])) == NULL) {
fprintf(stderr, "%s: No letter %c in %s\n", prog, argv[2][0], argv[1]);
exit(EINVAL);
}
if (*++p == 0 || (q = strchr(p, argv[2][1])) == NULL) {
fprintf(stderr, "%s: No letter %c in %s\n", prog, argv[2][1], argv[1]);
exit(EINVAL);
}
printf ("answer = ");
for (r = p; r < q; r++) {
putchar(*r);
}
printf ("\n");
return 0;
}
この回答への補足
すいません・・表題に書いているように文字列と文字列です。独自に調べていてstrchrが使えるんじゃないだろうか?という思い出strchrの関数のことを書いたのです。abからxyzの間というような感じにもしたいです。引数処理の部分まで書いていただいてありがとうございます。
検索する文字列には複数の対応する文字列があるはずです・・おそらく、
jasdlesjasdfieleというようにjaとleは二箇所あります。くるくる回して検索すればいいのだと思いますが・・文字列の場合どうなるのかご教授ください。
No.3
- 回答日時:
>strchrで位置のアドレスを取得してそこからfor文かwhile文で指定の2文字目が出るまでまわすのかなぁ・・と思っています。
それで良いと思います。
参考
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char *cut(const char *str, const char sc, const char ec, char *buff){
/* str の sc から ec の前までの文字列をbuff に切り出す */
char *wk, *s, *e;
wk=strdup(str); if(wk==NULL)return NULL;
s=strchr(wk, sc); if(s==NULL) return NULL;
e=strchr(s+1, ec); if(e==NULL) return NULL;
*e='\0';
strcpy(buff, s);
free(wk);
return buff;
}
int main(void){
const char text[]="abcdefghij";
const char url[]="/usr/bin/";
char buff[32];
printf("c~h:%s\n", cut(text, 'c', 'h', buff));
printf("/~/:%s\n", cut(url , '/', '/', buff));
return 0;
}
この回答への補足
前回も一度お世話になり、大変ありがとうございます。/* str の sc から ec の前までの文字列をbuff に切り出す */と書いていただいていますが・・やりたい処理は文字列と文字列の間です・・scからでは無くscの後からecの前までということです・・紛らわしくて・・本当にすいません・・
補足日時:2006/02/28 19:44お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Excel(エクセル) Excelにて、フォルダ内のTextファイルをマクロで統合すると文字化けしてしまう時の解消コード 4 2023/01/01 07:32
- C言語・C++・C# C言語で 英文字のみからなる文字列、”Radar”、”WasItACatISaw”、”a”、””(空 5 2022/12/20 15:17
- Excel(エクセル) LEFT関数で文字数を指定しないで取りだす方法 7 2023/06/30 09:49
- JavaScript javascriptで文字分割は、 split() などメソッド不要??? 4 2023/02/06 22:50
- Excel(エクセル) Excelのマクロで、特定のセルから順番に値を取得したい 5 2022/12/06 15:34
- Visual Basic(VBA) 特定の文字を簡単な操作で半角スペースに変換するか削除したい 2 2022/11/01 10:35
- オープンソース 【ChatGTPのオープンソースソフトウェアを解析したことがある方、教えてくださ 2 2023/03/08 18:57
- その他(コンピューター・テクノロジー) 【Tableau Desktop】文字列から8桁の数字を日付型(yyyyMMdd)として取得 1 2023/07/31 10:17
- PHP PHPの構文で間違えが分からない 5 2022/07/11 16:38
- Java Javaの問題なのですが、「3文字以上の英数字文字列を入力し、文字列の中に文字(9)が出てくるまでの 1 2023/06/06 18:55
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
間接参照のレベルが異なっています
-
fgetsなどのときのstdinのバッ...
-
C言語のfor文です。 繰り返しの...
-
文字列から空白を取り除きたい...
-
-'0'の意味について
-
charからLPTSTRへの変換方法
-
C言語の入力した文字を反転させ...
-
c言語でユーザ関数を利用して入...
-
Linuxでフォルダ内全ファイル名...
-
間接操作のレベルとは
-
型変換
-
構造体の各メンバにfor文からア...
-
c言語配列の結合についてです。...
-
TCHAR文字列?の特定部分の数字...
-
DxLibについて質問です
-
'const char *' 型は 'char *' ...
-
c言語でソーベルフィルタが作り...
-
CStringをwchar_tに変換したい
-
ADOレコードセット操作(Forルー...
-
エラーの意味
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
fgetsなどのときのstdinのバッ...
-
文字列から空白を取り除きたい...
-
間接参照のレベルが異なっています
-
C言語のfor文です。 繰り返しの...
-
CStringをwchar_tに変換したい
-
テキストデータをそのままバイ...
-
charからLPTSTRへの変換方法
-
atoi( ) の反対をやりたい
-
charでの計算?
-
配列をnビットシフトする
-
c++ 文字列を入力して、一文字...
-
'const char *' 型は 'char *' ...
-
c言語でユーザ関数を利用して入...
-
干支のプログラム
-
switch文で文字を比較すること...
-
char型からのバイト数取得
-
ネットワークにつながっている...
-
getchar()を int でとる理由...
-
間接操作のレベルとは
-
str系関数を使わずに二つの文字...
おすすめ情報