質問投稿でgooポイントが当たるキャンペーン実施中!!>>

初心者です。みなさまどうか教えてください。(>_<)

文字列置換関数をつくれ
ただし文字列操作系関数はつかうな(str---)。
void replace(char*str, char*before,char*after);

質問者からの補足コメント

  • すみません(>_<)
    strのなかにbeforeがあればafterで置き換える。それぞれ文字列長さは不定で複数あればすべて置換します。

      補足日時:2016/09/21 20:46
  • 何度も補足申し訳ございません。
    とりあえず自分で考えた部分は
    ♯include〈stdio.h〉

    void replace(char*str, char*before, char*after)

    int i, j, y;

    for(i=0; str[i]!=′¥0′; i++){
    for(j=0; before[j]!=′¥0′; j++){
    if(str[i+j]==before[j]){
    y==1;
    }
    }
    }

    int main()
    { char str[3000];char*before[1000];char*after[1000]続く

      補足日時:2016/09/22 07:33
  • scanf(“%s”, str);
    scanf(“%s”, before);
    scanf(“%s”, after);
    replace(str, before, after);
    printf(“置き換えた文字列%s”, str);
    return 0;
    }

      補足日時:2016/09/22 07:39

このQ&Aに関連する最新のQ&A

A 回答 (6件)

以下のようにしてください。


---------------------------------------------
#include <stdio.h>
#include <string.h>
//自前の文字列操作関数
//strのlengthを返す(自前のstrlen)
int mystrlen(char *str){
int i = 0;
while(*str){
i++;
str++;
}
return i;
}
//メモリの比較を行う(自前のmemcmp)
int mymemcmp(void *str1,void *str2,int len){
unsigned char *s1 = (unsigned char*)str1;
unsigned char *s2 = (unsigned char*)str2;
int i = len;
if (len == 0) return 0;
while(*s1 == *s2){
i--;
if (i == 0) return 0;
s1++;
s2++;
}
return (*s1 - *s2);
}
//メモリのコピー(str1<--str2)(自前のmemmove)
void mymemmove(void *str1,void *str2,int len)
{
unsigned char *s1 = (unsigned char*)str1;
unsigned char *s2 = (unsigned char*)str2;
if (s1 < s2){
while(len > 0){
len--;
//前からコピー
*s1++ = *s2++;
}
}else{
while(len > 0){
len--;
//後ろからコピー
*(s1+len) = *(s2+len);
}
}
return;
}
//メモリのコピー(str1<--str2)(自前のmemcpy)
void mymemcpy(void *str1,void *str2,int len)
{
unsigned char *s1 = (unsigned char*)str1;
unsigned char *s2 = (unsigned char*)str2;
while(len > 0){
len--;
*s1++ = *s2++;
}
return;
}
//課題の関数
//myxxxxのmyをとり実際に存在するxxxxを呼び出しても同じ結果が得られる筈
//例 mystrlen--->strlen
//例 mymemcmp--->memcmp
//例 mymemcpy--->memcpy
//例 mymemmome--->memmove
void replace(char *str,char *before,char *after)
{
int slen = mystrlen(str);
int blen = mystrlen(before);
int alen = mystrlen(after);
int len;
char *s = str;
char *from;
char *to;
/*
if (blen < alen){
printf("afterの長さ>beforeの長さの為処理を中止します\n");
return;
}*/
while(*s){
//str中にbeforeがあるかチェックする
if (mymemcmp(s,before,blen) == 0){
//存在する場合
//beforeの後の文字列の移動
from = s + blen;
to = s + alen;
len = mystrlen(from);
mymemmove(to,from,len);
//終端に\0を設定
*(to+len) = '\0';
//文字列の置換
mymemcpy(s,after,alen); //mymemmoveを使用しても問題ない
//次は置換された文字列の次から処理する
s = to;
continue;
}
s++;
}
}
//replace呼び出し前後のstr,bofore,afterの内容を表示
void test(char *str, char *before,char *after)
{
printf("実行前\n");
printf("<%s> <%s> <%s>\n",str,before,after);
replace(str,before,after);
printf("実行後\n");
printf("<%s> <%s> <%s>\n",str,before,after);
}
int main(void)
{
char str[256];
strcpy(str,"abcXXefgXXxyzXX");
test(str,"XX","YYY");
strcpy(str,"abcXYZefgXYZxyzXYZ");
test(str,"XYZ","AB");
strcpy(str,"abcXXXXXX");
test(str,"XX","ABCD");
return 0;
}
----------------------------------------------
以下、実行結果です。
実行前
<abcXXefgXXxyzXX> <XX> <YYY>
実行後
<abcYYYefgYYYxyzYYY> <XX> <YYY>
実行前
<abcXYZefgXYZxyzXYZ> <XYZ> <AB>
実行後
<abcABefgABxyzAB> <XYZ> <AB>
実行前
<abcXXXXXX> <XX> <ABCD>
実行後
<abcABCDABCDABCD> <XX> <ABCD>
    • good
    • 1
この回答へのお礼

わー!!ありがとうございます!!!

さすがです(。>ω<。)助かりました。何度も復習し頑張ります!!

本当にありがとうございました(〃'▽'〃)

お礼日時:2016/09/22 11:14

「何度も復習し頑張ります」の前にすべきことがあるんじゃないかな~.



この問題だと「文字列を置き換える」ことを要求されているんだけど, 「どういう処理をすれば『文字列の置き換え』ができるのか」って考えた? アルゴリズムがわからなかったらプログラムなど書けるはずもないよ.
    • good
    • 0
この回答へのお礼

そうですね。だいぶ考えました。流れはわかっていたのですがそれをプログラム化する力が現在では全く足りなかったのでお力を借りました。

お礼日時:2016/09/23 02:35

念の為、確認しますが、beforeの文字列よりもafterの文字列のほうが大きい場合は、strが破壊される場合があります。


以下のようなケースです。
strの内容が"abXYab"
beforeの内容が"XY"
afterの内容が"ABCD"
のとき、
置き換えた結果は、
"abABCDab"
となりますが、
strのサイズを呼び出し側で
char str[7];
としていた場合、メモリが破壊されます。
strのサイズを呼び出し側で
char str[9];
としていた場合は、メモリは破壊されません。
呼び出し側は、strのサイズをメモリが破壊されない為の十分大きなサイズを確保してある
という前提で良いでしょうか?
いいかえれば、故意にstrを小さなサイズで確保し、replaceを呼び出した場合、メモリ破壊が発生するが、
それはかまわない。
という前提で良いでしょうか。
    • good
    • 1
この回答へのお礼

回答ありがとうございます!

はい。問題文には呼び出し元(main関数)でstrは置き換え後の文字列を十分格納できることが前提とかいてありました。

説明不足で申し訳ございません(>_<)

お礼日時:2016/09/22 10:38

質問文にあるプロトタイプ宣言の通りであれば、実現不可能です。


beforeよりもafterの方が長いとアウトです。
実は次のようなインタフェースではないですか?
void replace(char**str, char*before,char*after);
もしくは、
char * replace(char*str, char*before,char*after);
とか。
    • good
    • 1
この回答へのお礼

回答ありがとうございます(。>ω<。)そうなんですか…問題をみるかぎり上記のようにはなってないのです。。よくわからない問題で申し訳ございません

お礼日時:2016/09/22 07:41

「初心者」だからなんだというのか.



どこまでできて, どこで困っている?
    • good
    • 0
この回答へのお礼

そうですよね、申し訳ございません。。

補足追加させていただきましたがご覧の通りほぼとけておりません。。

お礼日時:2016/09/22 07:43

char*str の仕様がわからない

    • good
    • 1
この回答へのお礼

早速の回答ありがとうございます。
そうですね。。私もわからず申し訳ございません

お礼日時:2016/09/22 07:44

このQ&Aに関連する人気のQ&A

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

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Q文字列置換C言語 置換前<置換後の場合

例えば文字列abcdef
のbcdをzzzzにして
azzzzefなど置換前文字列数<置換後文字列数にする文字列置換についておしえてください。前回もおたずねしたのですが、置換後文字列が増えるパターンのみわかりません。ちなみにライブラリ関数はつかえません。

とりあえずわかったことが
置換前bcd
置換後zzzz
のながさをそれぞれblen, zlenとし、

if(zlen<blen){
¥0をblen-flen分動かす
  ¥0のとなりのfから順にf、e…と順に代入して  いく
   }

ということです。わかりづらくて申し訳ございませんがよろしくお願いします

Aベストアンサー

No2です。
memmoveの実装について述べてなかったので、念の為述べておきます。
memmoveの実装ですが、以下のようになっています。
下図のc,d,e,fをaの位置へ転送する場合:
コピー先のアドレスがコピー元のアドレスより小さい場合は、前から1文字ずつ転送します。
もし、後ろから転送すると、c,dの文字が転送中にコピー元の文字でつぶされ、正しくコピーできません。

下図のc,d,e,fをeの位置へ転送する場合:
コピー先のアドレスがコピー元のアドレスより大きい場合は、後ろから1文字ずつ転送します。
もし、前から転送すると、e,fの文字が転送中にコピー元の文字でつぶされ、正しくコピーできません。

尚、コピー元とコピー先のアドレスの場合は、どちらから転送しても構いません。
(そもそも、同じところにコピーなので、何の処理をせずにリターンしても構わない。)

QC言語で文字列置き換え

をしたのですが

取得した値でC:\\programfile\\LOGがあり
文字列処理を行ってLOGをRESULTにかえ
C:\\programfile\\RESULT
としたいのですがうまくいきません。
strtokを使って、その後にstrcatで連結させようとしたのですが・・・。教えてください><

Aベストアンサー

>C:\\programfileを表示させたいのですがうまくいきません。
#2のプログラムでは、
最後の「\」を見つけて、その次の文字を「'\0'」に置き換えています。
"C:\\programfile\\\0"
にするというような意味合いです。
*(p+1)='\0';
でそれをやっています。
pが最後の「¥」の位置です。
これを取り除くなら
*p='\0';
とします。

QCの文字操作(置換)について

Cを始めたばっかりのものです。
いままでPerlとPHPでCGIを書いてますが、それをCに書き換えています。

今のところフォームをデコードして、nameを入れるとvalueを返す関数をつくって、さあこれから、という状況です。

基本的な質問ですが、Cには文字列の置換をしてくれる関数ってありますか?
たとえば、標準のライブラリに入ってなくても、どっかからダウンロードできるとか。
なければstring.hに入っている関数を使って自分で作ろうかと思ってますが、作った後に、“xxxxをつかったら一発でできるじゃん”という発見がすごいショックで、今までもなんどもありましたので、おたずねします。

よろしくお願いします。

Aベストアンサー

> これでなぜ漢字コード非対応なのかがよくわかりません。 置き換えられる対象文字(substr1)が1バイト文字1文字ではなく、2文字以上もしくは2バイト文字だったら文字コードが重なる可能性が少なくて、strstrでも2バイト文字の1バイト部分を切ったりしないと考えて大丈夫ですか?

この点については漢字コードの種類に依存します。例えばシフトJISの場合、2バイトのうちの1バイト目と2バイト目のコードの範囲は重なっています。このため、ある漢字1文字をsubstr1に指定した場合、2文字続く2バイト文字(全4バイト)の中央の2バイトが置換されてしまう可能性があります。また、一般には2バイト文字は1バイト文字と混在しているので、問題はさらに複雑になります。私はあまり詳しくないのですが、シフトJIS以外の漢字コードも同様の問題を抱えていると思います。

Qfgetsで拾われる改行文字を削除したい

お世話になります

 C言語初心者のものです。今課題でC言語を用いたプログラミングを
Fedora上でやっています。問題は、fgetsでテキストファイルから、取得
した文字列の中から改行文字を削除できないことです。文字変数のアド
レスはわかっているのですが、終端文字に置換しようとすると、セグメ
ントエラーになってしまいます。これは如何にして解決すべきでしょう
か。よろしくお願いします。

Aベストアンサー

ポインタとかアドレスとか、C言語の用語としてあるものを別の意味に使うとまぎらわしいです。

「ポインタ」「アドレス」と言われたら、 この例なら str, str+i が思い浮びます。
「文字変数のアドレス」だと
char c ;
に対しての
&c
が思い浮びます。

配列なら「添字」、意味的には「x文字目」ですね。

> for(i=0;;i++){
> if(*(str+i)=='/n') {
> *(str+i)='\0';
> break;
> }
> }
/nが\nの間違いなら、この方法で半分正解です。もう少し広い範囲(可能なら全体)で見ないことにはなんとも言えません。
fgetsが最大文字数に達したり、ファイルの最後になったりで、strに改行文字が含まれない場合には、このループは止まりません(Segmentension Falutになって止まる)

・そのような状態になってないか、予めチェックする
・ループを終了させる仕組みを用意しておく
: forの終了条件を記述する、for中で if(*(str+i)=='\0') { break;} 等としておく、等
といった対策が必要です。


あと細かいところを言えば
・strを配列で用意したなら *(s+i)じゃなくてs[i]でいいんじゃないかな
・あるいは char *pみたいにしておいて、 iのループでなく pでループを組む( for(p=str;*p!='\0';p++) )とか。

ポインタとかアドレスとか、C言語の用語としてあるものを別の意味に使うとまぎらわしいです。

「ポインタ」「アドレス」と言われたら、 この例なら str, str+i が思い浮びます。
「文字変数のアドレス」だと
char c ;
に対しての
&c
が思い浮びます。

配列なら「添字」、意味的には「x文字目」ですね。

> for(i=0;;i++){
> if(*(str+i)=='/n') {
> *(str+i)='\0';
> break;
> }
> }
/nが\nの間違いなら、この方法で半分正解です。もう少し広い範囲(可能なら全体)で見ないことにはなんとも言えません。
fgetsが...続きを読む

QLNK2019: 未解決の外部シンボルのエラーが出る

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自キャラのデータ
Point2D g_jikipos = {40, 400};//自キャラの座標

//画像ハンドル
int g_jikiimage[11];

//色々なファイルの読み込み
int LoadFiles(){
//画像ファイル読み込み
if(LoadDivGraph("media\\player01.bmp",
11,11,1,64,64,g_jikiimage) == -1) return -1;

return 1;
}


 mymain.h
//他から呼び出させるMyMainの関数
void MyMain();
int LoadFiles();


 myhelper.h(サンプルなので打ちミスはない)
#include "DxLib.h"
#include <limits.h>
#include <math.h>

//構造体宣言
//座標またはベクトルを記録する構造体
struct Vector{
float x,y;
};
typedef Vector Point2D;
//線を記録する構造体
struct Line2D{
Point2D startpos, endpos;
float katamuki;//傾きをラジアン値で記録
Vector speed;//移動している場合は速度をセット
};
//球体を記録する構造体
struct Ball2D{
Point2D position;
float hankei;//半径
};
//四角形を記録する構造体
struct Rect2D{
Point2D lefttop;
Point2D rightbottom;
float width;
float height;
};


//ライブラリ関数
Point2D PosInView(Point2D in);
int XInView(float inx);
int YInView(float iny);
void ScrollToLeft(float jikiposx);
void ScrollToRight(float jikiposx);
void ScrollToUp(float jikiposy);
void ScrollToDown(float jikiposy);
void DrawLineInView(float x1, float y1, float x2, float y2, int Color, int Thickness);
void DrawCircleInView(float x, float y, float r, int Color, int FillFlag);
void DrawAnimation(float x, float y, double ExtRate, double Angle,int TurnFlag,
int *imgarray, int allframe, float fps);
//ベクトル関数
Vector CreateVector(Vector in, float veclen);
Vector AddVector(Vector v1, Vector v2);
Vector SubVector(Vector v1, Vector v2);
Vector AddVectorInFrameTime(Vector pos, Vector speed);
Vector AddVectorInFrameTime2(Vector pos, Vector speed, Vector accel);
Vector Normalize(Vector in);
Vector RotateVector(Vector in, float radian);
float VectorLengthSquare(Vector in);
float DotProduct(Vector v1, Vector v2);
float CrossProduct(Vector v1, Vector v2);
void SetLine2DKatamuki(Line2D *in);
void DrawLine2D(Line2D in, int Color, int Thickness);
void DrawBall2D(Ball2D in, int Color, int Fill);
//当たり判定関数
bool HitTestLineAndBall(Line2D linein, Ball2D ballin);
bool IsPointAtLineFace(Line2D linein, Point2D ptin);
bool HitTestLineAndLine(Line2D line1, Line2D line2);
bool HitTestBallAndBall(Ball2D a, Ball2D b);
bool HitTestPointAndBox(Rect2D rect, Point2D pt);
//タイマー関数
void SetSimpleTimer(int idx, int time);
int GetPassedTime(int idx);


//グローバル変数
extern float g_frametime;
extern Rect2D g_framerect;//画面領域(当たり判定)
extern Point2D g_current_field_pos;//現在の左上座標
extern Rect2D g_stagesize;//ステージサイズ

//定数宣言
const float ZEROVALUE = 1e-10f;
const float PIE = 3.1415926f;
const int SCROLL_LIMIT = 200;
----------------------------------------------------------------
 エラー内容
1>myhelper.obj : error LNK2019: 未解決の外部シンボル "void __cdecl MyMain(void)" (?MyMain@@YAXXZ) が関数 _WinMain@16 で参照されました
1>C:\Documents and Settings\Owner\My Documents\Visual Studio 2008\Projects\my\Debug\my.exe : fatal error LNK1120: 外部参照 1 が未解決です
1>my - エラー 2、警告 0
ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ
----------------------------------------------------------------
画像を貼り付けときます
(見えにくい場合→http://www.dotup.org/uploda/www.dotup.org154142.jpg.html)
初心者なのでわかりやすくお願いします

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自...続きを読む

Aベストアンサー

ファイル構成から推測するに
mymain.cpp というファイルに
void MyMain(void) {
// ここに処理を書く
}
という関数が必要なようです。

QC言語で文字列をかえす正しい書き方が知りたいです?

C言語で次の警告が表示されます。
文字列を返したいのですが、正しい書き方はどのようにすれば良いのでしょうか?


jci.h(20) : warning C4172; ローカル変数またはテンポラリのアドレスを返します。


char *test(char *a, int b)
{
char str[BUFSIZ];
return str; <------

}

Aベストアンサー

再入可能にするかどうかで、回答は変わります。

A.2度呼び出した場合に前のデータを破壊してもよいケース(再入不可能)

char *test(...)
{
static char str[BUFSIZ]; // static指定でメモリは静的に確保されます。

...

return str;
}

B.2度呼び出した場合に前のデータを破壊しないケース(再入可能)
B-1.mallocを使ってもいいケース
char *test(...)
{
char *str;
str = malloc(BUFSIZ);
if(str == NULL) return NULL; // エラー

...

return str;
}
この場合は、呼び出し元でちゃんとfreeしましょう。

B-2.呼び出し元でメモリを確保するケース
(注意:同じアドレスを指定して複数回呼び出すと、メモリ内容は当然破壊されます)
char *test(char *str, ...)
{

...

return str;
}
これは#1の方の回答と同じです。

B-3.B-1/B-2の複合
(注意:NULL以外の同じアドレスを指定して複数回呼び出すと、メモリ内容は当然破壊されます)
char *test(char *str, ...)
{
if(str == NULL)
{
str = malloc(BUFSIZ);
if(str == NULL) return NULL; //エラー
}

...

return str;
}

こんなところですかね。

再入可能にするかどうかで、回答は変わります。

A.2度呼び出した場合に前のデータを破壊してもよいケース(再入不可能)

char *test(...)
{
static char str[BUFSIZ]; // static指定でメモリは静的に確保されます。

...

return str;
}

B.2度呼び出した場合に前のデータを破壊しないケース(再入可能)
B-1.mallocを使ってもいいケース
char *test(...)
{
char *str;
str = malloc(BUFSIZ);
if(str == NULL) return NULL; // エラー

...

return str;
}
この場合は、呼び...続きを読む

Q複数桁10進数の*桁目だけを抽出したい

タイトルがすべてと言えてしまうのですが、
例えば、int宣言された"4287"(この値は変動します)という数値があったとして、1桁目の"7"だけを別の変数へ引き抜きたいのですが、その場合にはANDによるマスク処理による演算で処理可能なのでしょうか?
また、他に良い方法などありましたら教えていただけますでしょうか?

Aベストアンサー

★10進数ですので AND は使えませんね。
・簡単なサンプルを載せますので読み取って下さい。

サンプル1:
int value = 4287;
int a[ 4 ];

a[0] = (value % 10); value /= 10; // 1桁目を取り出す
a[1] = (value % 10); value /= 10; // 2桁目を取り出す
a[2] = (value % 10); value /= 10; // 3桁目を取り出す
a[3] = (value % 10); value /= 10; // 4桁目を取り出す

サンプル2:
int value = 4287;
int a;

a = (value % 10);
value -= a;

value → 4280
a → 7
になります。

QC言語での文字列取得についてです。

 いつもお世話になっております。

 例えば、"AAA=C:\aabbcc\ddd"のような文字列があります。C言語だと、この文字列の"C:\aabbcc\"部分だけ抜き出す方法がわかりません。

 すいませんが、教えてください。

 

Aベストアンサー

今時string型を使わないでプログラムを組むのは時間の無駄です
これは最近のほとんどのC/C++コンパイラで使えます
char s[256]に問題の文字列が入っているとします

#include <string>
#include <iostream>
using namespace std;

void main(void)
{
chars[256];
stringstr;

strcpy(s,"AAA=C:\\aabbcc\\ddd");cout<<s<<endl<<endl;
str=s;
cout<<"前の削除"<<endl;
str.erase(0,str.find('=')+1);
cout<<str<<endl;
cout<<"後の削除"<<endl;
str.erase(str.find_last_of('\\')+1);
cout<<str<<endl;
}

結果:

AAA=C:\aabbcc\ddd

前の削除
C:\aabbcc\ddd
後の削除
C:\aabbcc\

なおリンクの無償ボーランドC++5.5でやりました

参考URL:http://www.borland.co.jp/cppbuilder/freecompiler/

今時string型を使わないでプログラムを組むのは時間の無駄です
これは最近のほとんどのC/C++コンパイラで使えます
char s[256]に問題の文字列が入っているとします

#include <string>
#include <iostream>
using namespace std;

void main(void)
{
chars[256];
stringstr;

strcpy(s,"AAA=C:\\aabbcc\\ddd");cout<<s<<endl<<endl;
str=s;
cout<<"前の削除"<<endl;
str.erase(0,str.find('=')+1);
cout<<str<<endl;
cout<<"後の削除"<<endl;
str.erase(str.find_last_...続きを読む

Qファイルやディレクトリの存在確認を行う方法

ファイルをオープンするのはfopenでOKですが、ファイルやディレクトリの存在確認を行う方法が知りたいです。

何か組み合わせて作るものなのでしょうか?
perlとか便利な演算子があるのですが、C/C++って器用ではないですね。
これは処理系?依存の内容ですか?

私の環境は VC6, VC2005 Windows2000です。

Aベストアンサー

int access(const char* path, int mode);
int stat(const char* path, struct stat* sb);

かな?
MSDN を引くと _access_s() を使えとか書いてあるけど。

Q文字列中に含まれる文字の個数をカウントするプログラムについて…

文字列、1文字が与えられたとき、これをポインタで入力し文字列中に含まれる文字の個数を計算するプログラムを作成せよ。

と、いう課題がだされたんですけど、ユーザが任意の文字列と1文字を入力できるようにすることができません…。
多分main関数の部分をちょっといじくればよいと思うのですが…。
どなたかアドバイスをお願いします。
#include <stdio.h>

int count(const char *str, const char ch)
{
int cnt=0;
while (*str!='\0')
{
if (*str==ch)
cnt++;
str++;
}
return cnt;
}

int main()
{
const char *str="hello,world!";
const ch='o';

int cnt;

cnt=count(str, ch);

printf("%s中に%cは%d個です\n", str, ch, cnt);


return 0;
}

文字列、1文字が与えられたとき、これをポインタで入力し文字列中に含まれる文字の個数を計算するプログラムを作成せよ。

と、いう課題がだされたんですけど、ユーザが任意の文字列と1文字を入力できるようにすることができません…。
多分main関数の部分をちょっといじくればよいと思うのですが…。
どなたかアドバイスをお願いします。
#include <stdio.h>

int count(const char *str, const char ch)
{
int cnt=0;
while (*str!='\0')
{
if (*str==ch)
...続きを読む

Aベストアンサー

scanf"%s", str)は、バッファオーバーフローの危険と改行文字の食べ残し問題がありますね。
-- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< --
int main()
{
char ch;
char str[BUFSIZ];
int cnt;

printf("文字列を入力して下さい > ");
fgets(str,BUFSIZ,stdin);

printf("カウントする文字を入力してください > ");
ch = getchar();

cnt=count(str, ch);
printf("%s中に%cは%d個です\n", str, ch, cnt);

return 0;
}


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング