C++言語で
char s[] = "AAABBBCCCDDDEEE";
という文字列があり、
3バイト毎、取り出して前に*をつけ
*AAA s=[BBBCCCDDDEEE]
*BBB s=[CCCDDDEEE]
*CCC s=[DDDEEE]
*DDD s=[DDD]
*EEE s=[]
のように表示させるプログラムで、
最後だけは3文字とは限らない場合も考慮した
最終的にsが空になるアルゴリズムを考えていますが
何か良い方法はありますか?
例)最後が3文字でない場合
*EE s=[] 2文字でした。
A 回答 (8件)
- 最新から表示
- 回答順に表示
No.8
- 回答日時:
#1 を C で書くなら
#include <stdio.h>
#include <string.h>
void foo(const char *str, int width)
{
const char *p = str;
size_t len;
for (len = strlen(str); len >= width; len -= width, p += width)
printf("*%.*s s=[%s]\n", width, p, p+width);
if (len)
printf("*%s s=[] %zu文字でした\n", p, len);
}
オーバースペック?
No.7
- 回答日時:
No.5 です。
No.6 さんの
>美しくない>#5.
>#4 を取り込めば cBak が不要になり, その結果 if の条件を < ではなく <= にすることができる.
確かに美しくなかったですね。
・No.4 さんの「回答」をじっくりと見れば良かった、と反省。
( → 早速、ブラウザのフォントを変更しました)
(プロポーショナルだと見づらくて・・、というか)勉強になりました。
今まで、この手の処理は、#5 のように「待避/復帰」で行っていました。
http://www.k-cube.co.jp/wakaba/server/format.html
で、懲りもせず、「ポインタでの処理」によるソースを投稿します。
★ No.6 さんも、#1 をコード化し、投稿してみませんか。
#include <stdio.h>
#include <string.h>
#define Tocyu(p) ((*p)*(*(p+1))*(*(p+2)))
int main()
{
char s[ 64 ] = "AAABBBCCCDDDEEE", *p;
p = s;
while( 1 ){
if( Tocyu( p ) ){
printf( "*%.3s s=[%s]\n", p, ( p + 3 ) ); // #4 さんのをパクリ
p += 3;
if( '\0' == *p ) break;
}
else{
printf( "*%-3s s=[] %d文字でした。\n", p, ( strlen( s ) % 3 ) );
break;
}
}
return( 255 );
}
注:インデントに全角空白を用いています。コピペ後、タブに一括変換して下さい。
No.6
- 回答日時:
美しくない>#5.
#4 を取り込めば cBak が不要になり, その結果 if の条件を < ではなく <= にすることができる.
これで仕様通り.
もちろん添え字の代わりにポインタを走らせることもできて, その方がもうちょっと C っぽいかもしれない. あと, for の中で毎回 if を通るのもアレなのでそこは for の条件を工夫して回避するといい... って, こうやっていくと最終的に #1 になりますが.
ああ, #1 も while じゃなくて for の方がよりきれいでしょうね. もちろん
p + =3;
は
p += 3;
の間違い.
No.5
- 回答日時:
>最後だけは3文字とは限らない場合も考慮した
「配列の添え字」による処理でのソースを投稿します。
最後が3文字の時も「3文字でした。」のメッセージが付いちゃうけど・・。
→ 最後が1,2,3文字でも共通処理(先頭 else の行)です。
>最終的にsが空になるアルゴリズムを考えていますが
「ポインタ」で処理し、文字列終端までポインタが移動=空、ということでしょうか?。
それでしたら↓は、参考程度に・・。
#include <stdio.h>
#include <string.h>
int main()
{
int i, iLen;
char s[64] = "AAABBBCCCDDDEEE", cBak;
iLen = strlen( s );
for( i = 0; i < iLen; i += 3 ){
if( ( i + 3 ) < iLen ){
cBak = s[ i + 3 ];
s[ i + 3 ] = '\0';
printf( "*%-3s s=[%c%s]\n", &s[ i ], cBak, &s[ i + 4 ] );
s[ i + 3 ] = cBak;
}
else printf( "*%-3s s=[] %d文字でした。\n", &s[ i ], ( iLen - i ) );
}
return( 255 );
}
注:インデントに全角空白を用いています。コピペ後、タブに一括変換して下さい。
No.3
- 回答日時:
全体の文字数を把握して、必要な文字数だけ、コピーして、毎回表示する。
基本は #1 のやり方がいいと思います。
プログラムなんて、人が書いたようにしか動きませんから
わからないときは、やろうとしていることをまずは机上で「人間」が処理して
今やったことを細かく分析するとくめるようになりますよ。
コンパイラの気持ちになって、処理してあげてください(笑
> 最後だけは3文字とは限らない場合も考慮した
> 最終的にsが空になるアルゴリズムを考えています
あなたなら、この部分(最後だけは3文字にならなった事)をどういう手段で「理解」しますか?
ただ、Cの場合、「移動」という手段を持っていないので
移動したい場合、
移動先へ「コピー」して移動元を「削除」することになります。
今回の場合、先頭部分を削除するだけなので、sの開始位置をずらすだけで
削除の代替となります。
もしも、中間を削除したいと思ったら、削除する部分よりも
先の部分をすべてコピーして削除部分に上書きするイメージになります。
その場合は、同一のメモリアドレスとなるので、memmove(3)を利用してください。
中間部分の削除もやってみればおもしろいと思いますよ。
http://www.linux.or.jp/JM/html/LDP_man-pages/man …
http://www.linux.or.jp/JM/html/LDP_man-pages/man …
No.2
- 回答日時:
#include <stdio.h>
#include <string.h>
int main(void)
{
int i;
char s[]="AAABBBCCCDDDEE";
char buf[5]="*___"; //buf[0]を'*'に、buf[4]を'\0'に初期化
char *p;
for (p = s;*p;) //ヌル文字になるまで実行
{
strncpy(&buf[1],p,3); //最大3文字コピー
for (i = 0;i < 3;i++) //いきなりpに+3しないのが重要
{
if (!*++p) break; //ヌル文字が来たら中断
}
printf("%s s=[%s]\n",buf,p);
}
return 0;
}
No.1
- 回答日時:
「s が空になる」の意味はわからんけど....
長さが 2以下であるような, 最後のときだけ特別扱いすればいいだけではないかな.
p=s;
残り長さ=strlen(p);
while (残り長さ >= 3) {
上のような表示
p + =3;
残り長さ -= 3;
}
if (残り長さ) {
最後の表示
}
って感じ.
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- その他(データベース) カラム上の重複を削除するクエリを教えてください 3 2022/04/12 14:11
- Excel(エクセル) ¥マークを含むパスの処理について(マクロ、または関数) 2 2022/12/25 02:11
- C言語・C++・C# C#の問題です。 文字列型の配列 s[100] にキーボードから入力された100文字以内の文字列(単 2 2022/06/22 15:18
- SQL Server ACCESSで3ファイルを結合して、表を作成するやり方を教えて下さい。 17 2022/08/15 20:34
- その他(プログラミング・Web制作) 変換のプログラムを教えてください。 6 2023/07/01 09:57
- Visual Basic(VBA) 【VBA】特定の文字で改行(次の行)に行きたい。 3 2022/04/11 17:20
- C言語・C++・C# C言語で 英文字のみからなる文字列、”Radar”、”WasItACatISaw”、”a”、””(空 5 2022/12/20 15:17
- C言語・C++・C# 【C言語】全角文字の配列を、全角のまま1文字ずつ出力する方法 4 2023/05/09 15:08
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- SQL Server ACCESSで複数テーブルを結合して、リストを作る方法を教えてください。 2 2022/08/12 19:32
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
ArduinoのジャイロモジュールMP...
-
mallocについて
-
C言語をコンパイルするとコンピ...
-
Windows Formアプリからコンソ...
-
大量のデータを読み込んで表示...
-
システムエンジニアの適正について
-
プログラミングの授業の課題です
-
C言語 列挙型(enum型)変数について
-
パイソン。If elseの挙動につい...
-
擬似コード 長さがmの配列でな...
-
プログラムを斜めに並べる
-
double型が正常に認識されてい...
-
gccを行ってもexeファイルが生...
-
プログラムが書けません。
-
C言語 配列と関数の練習問題
-
MACで動く実行ファイルをWindow...
-
int16_t の _t は何?
-
PC画面を録画するプログラムでd...
-
C言語階乗の総和を求める
-
Office Component Suite
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
gccを行ってもexeファイルが生...
-
あなたは、Excelはどうやって学...
-
WindowsのCapsLock(キャップス...
-
質問失礼します。 プログラム言...
-
double型が正常に認識されてい...
-
Notepad++の関数リスト表示でC...
-
どちのほうがすきですか?
-
Stuck
-
Notepad++の関数リスト表示の変...
-
ArduinoでMouse関数を使用して...
-
C言語の関数と配列に関する質問
-
C言語って古いですか?
-
Linuxでの開発環境構築や設定の...
-
Bitcoin、BTCはブロックチェー...
-
C++6.0でのresource.hについて
-
MACで動く実行ファイルをWindow...
-
C言語 列挙型(enum型)変数について
-
c言語
-
大量のデータを読み込んで表示...
-
こんなことてしますか??
おすすめ情報