アプリ版:「スタンプのみでお礼する」機能のリリースについて

下記が動かない。多分に、ポインターがおかしいと思うが。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
char *buf="<title>sample</title>";
char work[256];
char p;

char *out=work;
char *in=buf;

in=strstr(in,"<");
while(strcmp((p=(*out++ = *in++)),"sample") != 0);
printf("%c",p);

//while(strcmp((*out++=*in++),">") != 0);
*out='\0';
printf("%s\n",out);
return 0;
}
01.c: In function 'main':
01.c:14:2: warning: passing argument 1 of 'strcmp' makes pointer from integer without a cast [enabled by default]
while(strcmp((p=(*out++ = *in++)),"sample") != 0);
^
In file included from 01.c:3:0:
c:\mingw\include\string.h:43:37: note: expected 'const char *' but argument is of type 'char'
_CRTIMP int __cdecl __MINGW_NOTHROW strcmp (const char*, const char*) __MINGW_ATTRIB_PURE;

済みません。指摘をお願いします。

A 回答 (6件)

No.3です。


No.4の方へのお礼を拝見しました。

まず、strcmp()というのは、第1引数のポインタから始まる文字列と第2引数のポインタから始まる文字列とを比較し、一致する場合には0を、そうでない場合には0以外を返す関数です。ちなみに、文字列は最後の'\0'までをすべて比較しますので、これでは永遠に一致しません。この場合、strncmp()という、文字数を制限した比較関数を使います。
例:if (strncmp(start, "title", 5) == 0) { ...

>それならば、ポインターに型変換をする事は出来ないのでしょうか。

Cでは他のスクリプト言語と比べ、変数の表記、とりわけポインタが絡んだ場合にちょっと違う記法になります。

宣言の時:
char *a;

ポインタ(アドレス)として利用する場合:
strncmp(a, "title", 5);

ポインタで示される値を参照する場合:
printf("%c", *a);
→printf("%c", a[0]);と同じ動きになる

質問者様はおそらくこのあたりを混乱されているのだと思います。

>while(strcmp((p=(*out++ = *in++)),"title") != 0);

雰囲気的には、1行でこれを表現しようとしているのでしょうが、こういうことをするぐらいなら普通にブロックで書いた方が分かりやすいです。
while (strncmp(in, "title", 5) != 0) {
*out ++ = *in ++;
}
CはPerlと違い、行数が計算コストになるわけではありません。コンパイラが良しなに最適化してくれます。

さらにちなみにですが、大文字小文字を区別しない場合は、strncasecmp()という関数もあります。必要に応じて活用されればよいと思います。

これでお望みの回答になるのではないでしょうか?
    • good
    • 0
この回答へのお礼

有難う御座います。

何か、勘違いが有ったみたいです。
他の言語を知って居るのでどうしても先入観念と言うのは
拭い去るのは難しいですが。

strcmpとstrncmpですか。最初、何でこのstrncmpと言う
のが出るのかと思っていましたが。

少し整理をして見ます。どうも、私の考え違いが有った
様です。perlがメインですのでどうしてもその感覚から
抜けないです。相当に意識をしないといけない見たいです。

丁寧な回答有難う御座いました。
これで、閉じさせて頂きます。

有難う御座いました。

お礼日時:2017/02/26 16:39

No.3です。



No.4の方の問いかけに加え、次の情報も補足してください。

>コードでの回答の方がしっくり来ますし。また、理解もそれなりに早いです。

質問者様はどこまで理解できていて、何が分からないのでしょうか。

求める回答を得るためには、回答を引き出すための情報を与える必要があります。他の方々も、質問者様から出てくる情報が少なすぎるため回答に苦慮していることと思います。

もしくは、やりたいことを聞き取りしてもらうことから始めて最終的にプログラムを書いてもらうことを望んでいますか?でしたらお金を払って開発業者に依頼してください。
    • good
    • 1
この回答へのお礼

有難う御座います。
知りたいと所と言うのは、下記です。

このwhile文の中のstrcmpの最初の引数に問題が有ると思います。
strcmpの最初の引数は、charへのポインターとなっていますが。
多分に、私の*out++ = *in++ と言うのは、charのポインター
になっていないと思います。これを、ポインターに型変換をしたい。

説明が足りなくて申し訳有りませんが。宜しくお願いします。

お礼日時:2017/02/26 16:16

> 出来れば、この場合はstrcmpを使ったやり方と言うのを


> 例示願えれば宜しいのですが。

No.3の方が問うている3つのうち、質問者様がどれを望んでいるのかを明確にしたほうが良いですよ。
入力の"<title>sample</title>"に対して
workの中にどんな文字列が格納されれば正解なのでしょうか?
    • good
    • 1
この回答へのお礼

有難う御座います。
この場合は、titleです。

私の質問に間違いが有りました。
while(strcmp((p=(*out++ = *in++)),"sample") != 0);
上記は、正しくは
while(strcmp((p=(*out++ = *in++)),"title") != 0);
です。迷惑をおかけしました。煩わしい質問をしていました。

このwhile文の中のstrcmpの最初の引数に問題が有ると思います。
strcmpの最初の引数は、charへのポインターとなっていますが。
多分に、私の*out++ = *in++ と言うのは、charのポインター
になっていないと思います。

それならば、ポインターに型変換をする事は出来ないのでしょうか。
と言うのが質問の趣旨です。

分かりにくい質問をして済みません。
宜しく回答をお願いします。
自分の説明不足を痛感しております。宜しく、回答お願いします。

お礼日時:2017/02/26 16:05

No.2です。



>このタグの間に挟まれている文字を取得しようとする物です。

なるほど、やっとなんとなく意味が分かりました。

「<」と「>」の間にある文字列を取得したいということですか?
であればこれです。ただし、複数見つかった場合は連続して格納しています。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
char *buf="<title>sample</title>";
char work[256];
char p;

char *out=work;
char *in=buf;
char *end;
int len = 0;
work[0] = '\0';

while ((in = strchr(in, '<')) != NULL) {
// search '>' position
if ((end = strchr(in, '>')) == NULL) break;
// get length of string
len = end - in - 1;
strncpy(out, in + 1, len);
in = end + 1;
out += len;
}
*out = '\0';

printf("%s\n",work);
return 0;
}


もしくは「<~>」と「</~>」の間の文字列を抜き出すということですか?
であればこれです。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
char *buf="<title>sample</title>";
char work[256];
char p;

char *out = work;
char *in = buf;
char *end, *end2, *end3;
int len = 0;
work[0] = '\0';

while ((in = strchr(in, '<')) != NULL) {
// search '>' position of tagstart
if ((end = strchr(in, '>')) == NULL) break;
// search "</" position
if ((end2 = strstr(end, "</")) == NULL) break;
// search '>' position of tagend
if ((end3 = strchr(end2 + 1, '>')) == NULL) break;
len = end2 - end - 1;
strncpy(out, end + 1, len);
in = end3 + 1;
out += len;
}
*out = '\0';

printf("%s\n",work);
return 0;
}


それとも「<title>」と「</title>」の間の文字列を抜き出すということですか?
であればこれです。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define TITLE_TAG_S "<title>"
#define TITLE_TAG_S_LEN (sizeof(TITLE_TAG_S) - 1)
#define TITLE_TAG_E "</title>"
#define TITLE_TAG_E_LEN (sizeof(TITLE_TAG_E) - 1)

int main() {
char *buf="<title>sample</title>";
char work[256];
char p;

char *out = work;
char *in = buf;
char *end;
int len = 0;
work[0] = '\0';

while ((in = strstr(in, TITLE_TAG_S)) != NULL) {
// forward in at the end of <title>
in += TITLE_TAG_S_LEN;
// search "</title>" position
if ((end = strstr(in, TITLE_TAG_E)) == NULL) break;
len = end - in;
strncpy(out, in, len);
in = end + TITLE_TAG_E_LEN;
out += len;
}
*out = '\0';

printf("%s\n",work);
return 0;
}



以前の質問者様への回答の記憶から、質問者様はperlを自在に使いこなし、言葉にする前に頭の中で設計を済ませそのままコードに表現できる方とお見受けします。ただ、質問者様は一目瞭然とおっしゃいますが、当初の質問文ではコードにコメントすら書いてなく、残念ながら何がしたいか全く伝わってきませんので、質問者様の言葉を借りるならそれこそ時間の無駄です。今の時点でも3通りの回答をせざるを得ませんし、これが求めるものでなければさらにやり取りが長期化します。今後は設計内容をまず日本語で説明するなど、質問の仕方を工夫されるとよいと思います。
    • good
    • 1
この回答へのお礼

有難う御座います。
出来れば、この場合はstrcmpを使ったやり方と言うのを
例示願えれば宜しいのですが。

これと言うのは、最初からstrcmpの方法では実現は出来ないの
でしょうか。

出来れば余りstrcmpの方法以外からは、外れたくない物ですから。
折角回答されたのにもかかわらずにこの様な御願いをして
申し訳有りませんが。よろしくお願いします。

矢張り、この様な回答と言うのは言葉での説明よりかは
コードでの回答の方がしっくり来ますし。また、理解もそれなりに
早いです。

回答をお待ちしています。宜しくお願いします。

お礼日時:2017/02/26 15:30

No.1です。


では、プログラムで何をしたいかを教えてください。

上記質問文では、エラーが発生する原因を指摘しろとしか読めません。
さすがに私は普段日本語で会話しているので、何がしたいかわからない、しかも間違ったC言語のコードを見て何をしたいか読み取る能力はありません(きっと世の中のほとんどの人もそうでしょう)。ゆえにコードで示せと要求されても示すことができません。
    • good
    • 1
この回答へのお礼

有難う御座います。

コードを見れば一目瞭然の筈ですが。
*bufは、タグが入っています。このタグの間に挟まれている文字を取得
しようとする物です。

while文の中では、タグの終了の">"が終了条件に成っています。その中
で、work[]の配列に文字を詰め込むと言う事ですが。これって言うの
は、説明が要るのでしょうか。

そんな難しい事では無いですよね。C言語を全く知らないと言う人で無
い限りは。それよりも、コードでの回答をお願いします。

お礼日時:2017/02/26 14:18

私が見ているのはLinuxのgccですが、sting.hの中には、


extern int strcmp (const char *__s1, const char *__s2)
とプロトタイプ宣言されています。

対して、上記のコードでは
char p;
と宣言していて、strcmpの第1引数でポインタを指定していないからですね。
    • good
    • 0
この回答へのお礼

有難う御座います。

解説よりも、直にコードで提示願います。
そうしないと、相手に素直に話が通りません。
而も、それが必ずしも正解で無い場合も多々有ります。

この場合は、char pをchar *pにすると言う事でしょうか。
この様に、非常に質問をする方も答えをする方も
説明に時間ばかりがかかって苦慮します。

私は、きちんとコードで質問をしている訳ですので
回答もコードで提示願います。

私は、char p の宣言に問題が有ると思い、
char p を char *pに変更しましたが、下記のエラーが出ます。
01.c: In function 'main':
01.c:14:17: warning: assignment makes pointer from integer without a cast [enabled by default]
while(strcmp((p=(*out++ = *in++)),"sample") != 0);

回答をお待ちしています。
次からは、コードでの回答をお願いします。時間の無駄ですから。
コードの方が、一目瞭然で正確に伝わりますので強力をお願いします。

お礼日時:2017/02/26 13:39

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