タイトルの通り、ポインタを使って
回文(前から読んでも後ろから読んでも同じってやつです)
であるかどうか判断するプログラムを
作りたいのですが、
どうしてもうまく行きません。どうしたらいいでしょうか。
今の所こんな感じです
#include <stdio.h>
int main(void)
{
char string[256];
char *checkA, *checkB;
printf("Input String >> ");
scanf("%s", string);
for(checkA = string; *checkA != '\0'; checkA++){
;
}
checkB = string;
for(checkA = checkA - 1; checkA <= 0; checkA--){
*checkB = *checkA;
checkB++;
}
if(*checkA == *checkB){
printf("%s は左右対称です。\n", string);
}
else{
printf("%s は左右対称ではありません。\n", string);
}
return 0;
}
No.3ベストアンサー
- 回答日時:
おはようございます.
終了処理が怪しい為に一寸危険な感じになってますね.
ここでは,以下の方針を使います.
(1)文字列の長さの取得はstrlen()を使う
(2)ヌル文字での終端を保証するためにfgets()を使う
(3)前から走査するポインタと逆に走査するポインタで一文字づつ比較.
実装例として以下のような感じでどうでしょうか.
この場合,長さが奇数なら「真ん中の文字」を同時に参照した段階で止まります.
長さが偶数なら「となり同士の文字」で止まります.
参考までに.
#include <stdio.h>
#include <string.h>
#define MAX_STR 256
int main(void)
{
char string[MAX_STR];
char *checkA, *checkB;
int len, isanag;
printf("Input String >> ");
fgets(string, MAX_STR, stdin); /* scanfは安全じゃない */
len = strlen(string); /* 長さを取得 */
/* 文字列の長さが奇数なら自動的に終了する */
/* checkAは先頭から,checkBは最後尾から始める */
for(checkA = string, checkB = string + (len - 1), isanag=1;
(checkA !=checkB); checkA++, checkB--){
if(*checkB != *checkA){
isanag = 0;
break; /* 途中一文字でも違ったら終了 */
}
if((checkA+1)==checkB){
break; /* 文字列の長さが偶数の時の終了処理 */
}
}
if(isanag){
printf("%s は左右対称です。", string);
}
else{
printf("%s は左右対称ではありません。\n", string);
}
return 0;
}
No.9
- 回答日時:
#8です。
ポインタを使うんでしたね。以下のように直してください。static BOOL iskaibun(char *p) {
if ( p == NULL ) return FALSE; //NULLポインタの場合
WCHAR uni[256]; //UniCode取得用の領域
int a = MultiByteToWideChar(0,0,p,-1,uni,256) - 1;
if ( a <= 1 ) return FALSE; //有効字数が1以下の場合
WCHAR *seq = uni; //順方向のポインタ
WCHAR *rev = &uni[a - 1]; //逆方向のポインタ
for ( a /= 2 ; a > 0 ; a-- ) { //字数の半分の回数
if ( *(seq++) != *(rev--) ) return FALSE;
}
return TRUE;
}
No.8
- 回答日時:
漢字を考慮する必要があります。
考え方として、UniCode化してから比較すると楽です。
#include <windows.h>
static BOOL iskaibun(char *p) {
if ( p == NULL ) return FALSE; //NULLポインタの場合
WCHAR uni[256]; //UniCode取得用の領域
int a = MultiByteToWideChar(0,0,p,-1,uni,256) - 1;
if ( a <= 1 ) return FALSE; //有効字数が1以下の場合
for ( int b = 0 ; b < a ; b++ ) {
if ( uni[b] != uni[--a] ) return FALSE;
}
return TRUE;
}
int main(void) {
== 略 ==
if ( iskaibun(string) ) {
printf("%s は左右対称です。\n", string);
}
else {
printf("%s は左右対称ではありません。\n", string);
}
== 略 ==
★インデントに漢字空白を使っています。コピペ注意
MultiByteToWideCharは終端のNULL文字も字数として返すので、1を
減じてから使います。aは順方向、bは逆方向のインデックスです。
NULLポインタ、空文字列、1文字だけの場合はFALSEが返ります。
http://msdn.microsoft.com/ja-jp/library/cc448053 …
No.5
- 回答日時:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int kaibun(unsigned char *s)
{
unsigned char *p = s + strlen(s) - 1;
int i, j, k = (isalpha(*s) != 0);
while(s < p){
i = isalpha(*s);
j = isalpha(*p);
k |= (i || j);
if(i && j){
if(toupper(*s ++) != toupper(*p --)) return 0;
}
else{
s += !i;
p -= !j;
}
}
return k;
}
int main(void)
{
const char *result[] = {"回文ではありません。", "回文です。"};
char s[128];
scanf("%127[^\n]%*[^\n]%*c", s);
puts(result[kaibun(s)]);
return 0;
}
No.2
- 回答日時:
こんにちは。
別なやり方として
/* ポインタを使って前後が逆になっている文字列を作成する */
/* 元の文字列と逆の文字列とを文字列比較する */
ご参考までに。
No.1
- 回答日時:
どう「うまくいかない」のかを書きましょう。
まぁ現状ではSegmentation Faultだと思いますが。> for(checkA = checkA - 1; checkA <= 0; checkA--){
ループ終了条件が間違っているので、checkAがstringの先頭に到達しても終了せず更に前に行ってしまいます。
> *checkB = *checkA;
元文字列のstringを壊してます。また上記の通りループ終了条件が間違っているのでstringの終端に到達しても止まりません。
> if(*checkA == *checkB){
「文字列」の比較に論理演算子==は使えません。
僕の書いた奴だと先頭の文字だけ比較していたので
thatのようなものでもthatのtが同じだから
回文扱いされていました。
文字列の比較には==使えないんですか;
他の方がされているように
一文字一文字確認しないといけないですね;
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
これまでで一番「情けなかったとき」はいつですか?
これまでの人生で一番「情けない」と感じていたときはいつですか? そこからどう変化していきましたか?
-
【大喜利】【投稿~1/31】『寿司』がテーマの本のタイトル
【お題】 『寿司』がテーマの本のタイトルを考えてください
-
最強の防寒、あったか術を教えてください!
とっても寒がりなのですが、冬に皆さんがされている最強の防寒、あったか術が知りたいです!
-
洋服何着持ってますか?
洋服を減らそうと思っているのですが、何着くらいが相場なのかわかりません。
-
14歳の自分に衝撃の事実を告げてください
タイムマシンで14歳の自分のところに現れた未来のあなた。 衝撃的な事実を告げて自分に驚かせるとしたら何を告げますか?
-
C言語プログラミングについて(回文、palindrome)
C言語・C++・C#
-
入力した文字列から母音だけを出力するプログラム
C言語・C++・C#
-
c言語でポインタ変数を用いた配列の反転操作
C言語・C++・C#
-
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・思い出すきっかけは 音楽?におい?景色?
- ・あなたなりのストレス発散方法を教えてください!
- ・もし10億円当たったら何に使いますか?
- ・何回やってもうまくいかないことは?
- ・今年はじめたいことは?
- ・あなたの人生で一番ピンチに陥った瞬間は?
- ・初めて見た映画を教えてください!
- ・今の日本に期待することはなんですか?
- ・【大喜利】【投稿~1/31】『寿司』がテーマの本のタイトル
- ・集中するためにやっていること
- ・テレビやラジオに出たことがある人、いますか?
- ・【お題】斜め上を行くスキー場にありがちなこと
- ・人生でいちばんスベッた瞬間
- ・コーピングについて教えてください
- ・あなたの「プチ贅沢」はなんですか?
- ・コンビニでおにぎりを買うときのスタメンはどの具?
- ・おすすめの美術館・博物館、教えてください!
- ・【お題】大変な警告
- ・【大喜利】【投稿~1/20】 追い込まれた犯人が咄嗟に言った一言とは?
- ・洋服何着持ってますか?
- ・みんなの【マイ・ベスト積読2024】を教えてください。
- ・「これいらなくない?」という慣習、教えてください
- ・今から楽しみな予定はありますか?
- ・AIツールの活用方法を教えて
- ・最強の防寒、あったか術を教えてください!
- ・【大喜利】【投稿~1/9】 忍者がやってるYouTubeが炎上してしまった理由
- ・歳とったな〜〜と思ったことは?
- ・モテ期を経験した方いらっしゃいますか?
- ・好きな人を振り向かせるためにしたこと
- ・スマホに会話を聞かれているな!?と思ったことありますか?
- ・それもChatGPT!?と驚いた使用方法を教えてください
- ・見学に行くとしたら【天国】と【地獄】どっち?
- ・これまでで一番「情けなかったとき」はいつですか?
- ・この人頭いいなと思ったエピソード
- ・あなたの「必」の書き順を教えてください
- ・14歳の自分に衝撃の事実を告げてください
- ・人生最悪の忘れ物
- ・あなたの習慣について教えてください!!
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
CStringからchar*への型変換に...
-
C言語にて構造体のメンバがNULL...
-
char*を初期化したいのですが
-
C言語のintとcharの違いってな...
-
char型にint型の数値を代入する。
-
fstream型オブジェクトを関数の...
-
fgetc( )の戻り値はなぜ整数??
-
new charとnew char[N]の違いは?
-
文字列str内の全ての数字を...
-
C++Builder 2009 テキスト...
-
C++17で、unsigned char * 配列...
-
文字型配列に格納した空白の切捨て
-
コマンドライン引数 *argv[]は...
-
ASCIIコードへの変換方法
-
szとlpszの違い
-
C言語の文字リテラル中の16進文...
-
入力された文字列の中の数字を...
-
DWORDとcharの変換
-
C言語のプログラムについてです
-
csvファイルをfscanfで読み込む...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
CStringからchar*への型変換に...
-
char*を初期化したいのですが
-
C言語のintとcharの違いってな...
-
小数点入りの文字列をfloat型に...
-
C言語にて構造体のメンバがNULL...
-
char型にint型の数値を代入する。
-
csvファイルをfscanfで読み込む...
-
new charとnew char[N]の違いは?
-
文字型配列に格納した空白の切捨て
-
C++17で、unsigned char * 配列...
-
2次元配列の文字"列"の初期化方法
-
DWORDとcharの変換
-
入力された文字列の中の数字を...
-
char 文字列型 の表現範囲が-12...
-
fgetc( )の戻り値はなぜ整数??
-
fstream型オブジェクトを関数の...
-
C言語の文字リテラル中の16進文...
-
動的メモリの初期化方法について。
-
const char* s1とただのchar s1...
-
strcat関数を自作したいです
おすすめ情報