前提・実現したいこと
2つの文字列の変換をしたいです。Linuxでいうtrの機能をつくりたいです。
例として、
tr asd zxc
a
z
というふうに文字が変換されるプログラムを作りたいです。
ですが、下記のソースコードを実行すると、
tr asd zxc
a
a
というふうに文字が変換されません。
以前にも同じような質問をして、いただいた回答を参考にコーディングしてみましたが、限界を感じたので質問することにしました。
大変恐縮ではございますが、お力添えいただければ幸いです。
よろしくお願いいたします。
該当のソースコード
C言語
1 2#include<stdio.h> 3#include<string.h> 4#include<ctype.h> 5 6char moji1[100], moji2[100], moji3[100], moji4[100]; 7char *pmoji2, *pmoji3, *pmoji4; 8int tr(){ 9 int i; 10 while( 1 ){ 11 // 値の入力 12 scanf( "%s", moji4 ); 13 pmoji2 = moji2; 14 pmoji3 = moji3; 15 pmoji4 = moji4; 16 17 for( i = 0; i<='\0'; ++i ){ 18 if( strcmp( ( pmoji4+i ), (pmoji2+i ) ) == 0 ){ 19 if( strcmp( ( pmoji2+i ), (pmoji3+i ) ) != 0 ){ 20 printf( "%s\n", ( pmoji3+i ) ); 21 }else{ 22 printf( "%s\n", ( pmoji4+i ) ); 23 } 24 }else{ 25 printf( "%s\n", ( pmoji4+i ) ); 26 } 27 } 28 } 29 return( 0 ); 30} 31 32int main(){ 33 // 値の入力 34 scanf( "%s %s %s",moji1, moji2, moji3 ); 35 // trメソッドの呼び出し 36 if( strcmp( moji1, "tr" ) == 0 ){ 37 tr(); 38 } 39}
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/10/02 07:35
2019/10/02 07:36
2019/10/02 12:09
回答4件
0
strcmp は, 指定したアドレスから '\0' までを比較します.
prinf の "%s" は, 指定したアドレスから '\0' までを表示します.
文字列のバイト数は, strlen で取得できます.
投稿2019/10/02 07:50
総合スコア12646
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/10/02 07:58
2019/10/02 15:58
0
あまり参考にならないかもしれませんが。
C
1#include <stdio.h> // getchar, putchar 2#include <string.h> // strlen 3 4#define T2(x) x,x+1,x+2,x+3 5#define T1(x) T2(x),T2(x+4),T2(x+8),T2(x+12) 6#define T(x) T1(x),T1(x+16),T1(x+32),T1(x+48) 7unsigned char t[256] = { T(0), T(64), T(128), T(192) }; 8 9int main(int argc, char *argv[]) 10{ 11 if (argc != 3 || strlen(argv[1]) != strlen(argv[2])) 12 return fprintf(stderr, "usage: %s string1 string2\n", argv[0]), 1; 13 unsigned char b; 14 for (int i = 0; b = argv[1][i]; i++) t[b] = argv[2][i]; 15 int c; 16 while ((c = getchar()) != EOF) putchar(t[c]); 17}
追記
こう書けば参考になるのかな。
C
1#include <stdio.h> // getchar, putchar 2#include <string.h> // strlen 3 4unsigned char t[256] = { 5 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 6 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 7 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 8 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 9 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 10 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 11 96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111, 12 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, 13 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, 14 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, 15 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, 16 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, 17 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, 18 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, 19 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, 20 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255, 21}; 22 23int main(int argc, char *argv[]) 24{ 25 if (argc != 3 || strlen(argv[1]) != strlen(argv[2])) { 26 fprintf(stderr, "usage: %s string1 string2\n", argv[0]); 27 return 1; 28 } 29 int c; 30 unsigned char b; 31 for (c = 0; (b = argv[1][c]) != '\0'; c++) 32 t[b] = argv[2][c]; 33 while ((c = getchar()) != EOF) 34 putchar(t[c]); 35}
投稿2019/10/04 03:15
編集2019/10/04 21:10総合スコア8224
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
ベストアンサー
このままだと収束しない気がしたので、僭越ながら、回答をひとつ。
というふうに文字が変換されません。
当たり前のことを書きますが、変換されないのは、「変換されないようにコードを書いているから」です。
いっぺんに色々なことが出てきて混乱しているかもしれませんが、これまで使ったことが無い未知の関数、scanf
やstrcmp
の動作内容は把握されていますか? 何となく使って、出てきた結果のつじつま合わせをしていませんか?
まず頭の中で動きを確実にイメージしましょう。自分の頭と手と紙とペンを使ってその処理を逐一実行するととして、できますか? できたら、それをソースコードに反映するだけです。(実際は「だけ」では済みませんが) もし、trコマンドの実現が手に余ると言うのであれば、まだ課題としては難しいのかもしれません。
先のご質問 linuxのtrコマンドのような機能をつくりたいです の回答でアドバイスをいただいた件、
「文字の配列を1文字ずつ処理する方法」をマスター。。。あるいはマスターとまではいかないくても、作って、やってみましたか?それが出来れば、trへの応用もそんなに難しいことではないはずなのです。悔しいかもしれませんが、もう一歩戻るのも長い目で見て近道です。
ちなみに、下は簡易版 tr コマンドを私が作ってみた例です。コードは、あえて冗長に書いたところがあります。「こんな風にも書ける」程度に見てください。もっと良い例もあるでしょうし、ht3433 さんがこれを流用する必要はありません。ただ、もし中身が理解できなければ、まだ早いと言うことです。(失礼だったらごめんなさい)
バグや問題点のご指摘は歓迎しますが、中身の解説の依頼はご遠慮ください。
変換元のと変換先の文字列集合の指定には、コマンドラインオプションmain(int argc, char *argv[])
を使います。尚、全角文字は扱えません。
C
1/* simple_tr.c */ 2 3#include <stdio.h> 4#include <string.h> 5 6int translate(int cc, const char *ps1, const char *ps2) { 7 while (*ps1 != '\0') { 8 if (*ps1 == cc) { 9 return *ps2; 10 } 11 ++ps1; 12 ++ps2; 13 } 14 return cc; 15} 16 17int main(int argc, char *argv[]) { 18 if (argc < 3) { 19 fprintf(stderr, "Too few argument(s). ABORT!\n"); 20 return 1; 21 } 22 23 if (strlen(argv[1]) != strlen(argv[2])) { 24 fprintf(stderr, "Arg1 and arg2 must be same length! ABORT!\n"); 25 return 1; 26 } 27 28 int cc; 29 for (;;) { 30 cc = getchar(); 31 if (cc == EOF) { 32 break; 33 } 34 cc = translate(cc, argv[1], argv[2]); 35 putchar(cc); 36 } 37 38 return 0; 39}
Cygwin上でのコンパイル~実行例です。
Bash
1$ gcc -Wall simple_tr.c -o simple_tr.exe 2 3$ ./simple_tr.exe asd zxc 4a 5z 6s 7x 8d 9c 101 111 122 132 143 153 16123asd789 17123zxc789 18123asdASD 19123zxcASD 20
投稿2019/10/02 10:38
総合スコア9183
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/10/04 01:19
2019/10/04 01:55 編集
2019/10/04 05:48
2019/10/04 06:07
2019/10/04 06:44
2019/10/04 06:55
2019/10/04 08:26
2019/10/04 08:36
2019/10/04 08:54
2019/10/09 04:58
2019/10/09 05:06
2019/10/09 05:09
2019/10/09 05:12
0
きのついたとこだけ。
for( i = 0; i<='\0'; ++i ){
'\0' というのは0ってことなので、このループはiが0のときしか回りません
#最初の1回だけしか回らない
投稿2019/10/02 07:38
総合スコア87774
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。