
タイトルの通り、ポインタを使って
回文(前から読んでも後ろから読んでも同じってやつです)
であるかどうか判断するプログラムを
作りたいのですが、
どうしてもうまく行きません。どうしたらいいでしょうか。
今の所こんな感じです
#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も見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
CStringからchar*への型変換に...
-
char型にint型の数値を代入する。
-
ポインタ配列
-
コマンドライン引数
-
new charとnew char[N]の違いは?
-
C言語のintとcharの違いってな...
-
VC++ char[10]へのCString値の代入
-
C言語にて構造体のメンバがNULL...
-
wsprintf( ポインタ , "%d" , "...
-
文字列str内の全ての数字を...
-
文字列strの中から文字cを探す...
-
2次元配列の文字"列"の初期化方法
-
char 文字列型 の表現範囲が-12...
-
文字列を表すための配列とポインタ
-
C++17で、unsigned char * 配列...
-
csvファイルをfscanfで読み込む...
-
'\\0'とはなんですか?
-
VS2005 での修正
-
文字列内の数字削除
-
文字型配列に格納した空白の切捨て
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
CStringからchar*への型変換に...
-
char*を初期化したいのですが
-
C言語にて構造体のメンバがNULL...
-
C言語のintとcharの違いってな...
-
DWORDとcharの変換
-
C++17で、unsigned char * 配列...
-
char 文字列型 の表現範囲が-12...
-
new charとnew char[N]の違いは?
-
char型にint型の数値を代入する。
-
動的メモリの初期化方法について。
-
小数点入りの文字列をfloat型に...
-
文字型配列に格納した空白の切捨て
-
fstream型オブジェクトを関数の...
-
C++Builder 2009 テキスト...
-
文字列の途中から途中までを抽出
-
C言語の文字リテラル中の16進文...
-
エクセルのMID関数は、C言語では?
-
文字列のswap
-
void型へのポインタ
-
VC++ char[10]へのCString値の代入
おすすめ情報