タイトルの通り、ポインタを使って
回文(前から読んでも後ろから読んでも同じってやつです)
であるかどうか判断するプログラムを
作りたいのですが、
どうしてもうまく行きません。どうしたらいいでしょうか。
今の所こんな感じです
#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で質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# char string[100]; int c, i=0; while( (c=getchar()) 2 2022/05/30 21:41
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- C言語・C++・C# C++プログラミングコードにポリモーフィズムを取り入れ方を教えてください。 2 2023/06/09 11:17
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# C++初心者です stirng 2 2022/09/20 20:43
- C言語・C++・C# c言語でユーザ関数を利用して入力された文字列を反転させるプログラムを作りたいです。 3 2023/01/29 19:47
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# 10個の実数に対する降順ソート結果を出力するプログラムを作りたいのですが、以下のプログラムをどう直せ 1 2022/07/09 22:16
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
- Java java 入力 3 4 3 出力 ABC DEFG HIJ このようなプログラムの書き方を教えてくだ 2 2022/07/15 14:18
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
char*を初期化したいのですが
-
C言語のintとcharの違いってな...
-
CStringからchar*への型変換に...
-
C言語にて構造体のメンバがNULL...
-
入力された文字列の中の数字を...
-
new charとnew char[N]の違いは?
-
C言語:小文字を大文字に変換す...
-
DWORDとcharの変換
-
小数点入りの文字列をfloat型に...
-
プログラムの中身の意味
-
wsprintf( ポインタ , "%d" , "...
-
C言語のプログラムについてです
-
szとlpszの違い
-
Vectorでヒープエラーが出る
-
csvファイルをfscanfで読み込む...
-
fstream型オブジェクトを関数の...
-
エクセルのMID関数は、C言語では?
-
文字列内の数字削除
-
警告 : 問題のあるポインタの変換
-
しつこい様ですが、再度ポイン...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
char*を初期化したいのですが
-
CStringからchar*への型変換に...
-
C言語にて構造体のメンバがNULL...
-
C言語のintとcharの違いってな...
-
小数点入りの文字列をfloat型に...
-
new charとnew char[N]の違いは?
-
const char* s1とただのchar s1...
-
DWORDとcharの変換
-
strcat関数を自作したいです
-
C++17で、unsigned char * 配列...
-
文字列内の数字削除
-
エクセルのMID関数は、C言語では?
-
char 文字列型 の表現範囲が-12...
-
char型にint型の数値を代入する。
-
C言語を用いた環境変数の作成/...
-
動的メモリの初期化方法について。
-
fstream型オブジェクトを関数の...
-
C言語のプログラムについてです
-
文字列の途中から途中までを抽出
-
C言語:小文字を大文字に変換す...
おすすめ情報