C++ 文字を右にずらす問題

このQ&Aのポイント
  • C++文字を入力して、それを1つ右にずらして出力する問題。
  • 関数内でポインタを使用するのが条件で、ズラしているつもりが、入力した文字がそのまま出力されてしまいます。
  • ポインタを使用して文字列を右にずらすアルゴリズムを実装しようとしていますが、思った通りに動いていないようです。
回答を見る
  • ベストアンサー

C++

文字を入力して、それを1つ右にずらして出力する問題。 例  aret → tare 関数内でポインタを使用するのが条件です。 ズラしているつもりが、入力した文字がそのまま出力されてしまいます。 自分の方針としては、 関数内で入力された文字の長さを確認。 文字列の最後の文字をtmpに保存して ドンドン右にずらして保存していく。 最後にtmpに保存したものを、文字列の最初に入れる。 というものです。 わかるかた、ご指導お願いします。 #include<stdio.h> #include<string.h> void kaiten(char *t) { int len =0; int i; char tmp; while (*t++){ len++; } tmp = *(t+(len-1)); for(i=len-1;i>0;i--) *(t+i)=*(t+i-1); *t = tmp; } int main() { char s[100]; printf("文字列を入力:"); scanf("%s",s); kaiten(s); printf("一文字ずらすと:%s\n",s); }

質問者が選んだベストアンサー

  • ベストアンサー
  • chu2oyaji
  • ベストアンサー率31% (17/54)
回答No.3

> while (*t++){ len++; } ここで t が変わってしまいます。文字列終端+1かな。 その後の処理では t が入力された文字列の先頭を指している事を期待しているので、 意図した動きになっていないと思われます。

shoudd
質問者

お礼

なるほど!  char *p=t; と置き換えて、 while(*p++){len++;} とすることによって解決しました! ありがとうございました!

その他の回答 (2)

  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.2

> while (*t++){ このループを抜けたとき、tは一体どこを指しているでしょう? バッファが十分すぎる量なのでsegmentation faultにはなっていませんが、これがs[10]とかだとメモリ破壊しますよ。 本来strlenで十分ですし、あくまで計算で行う方針ならt+lenで行わなければ駄目です。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

t を変えちゃっていいの?

関連するQ&A

  • シーザー暗号(C言語)

    シーザー暗号というものを作ろうとしていますが、文字のずらし方がわからず詰まっています。 手順は一応考えてあります。 (1)入力された文字を配列input[301]に代入 (2)何文字ずらすかを指定してその数値を変数countに代入 (3)入力された文字の長さを変数lenに代入 (4)inputとcountとlenを、文字をずらしてそれをoutputに返す関数shiftに渡す (5)outputを表示する のような感じですが、肝心の文字のずらし方がわかりません。 JISコードを使ってやるといいと聞いたんですが、そのやり方がわかりません。 ソース↓ #include <stdio.h> #include <string.h> int shift_char(char x[], int y, int z) { int i; for(i = 0; i <= z; i++) { x[i] = x[i] + y; } return x; } int main(int argc, char* argv[]) { char input[301]; char output[301]; int count, len, i; printf("文字を入力してください: "); scanf("%s" ,input); printf("何文字ずらしますか: "); scanf("%d" ,count); len = strlen(input); output = shift_char(input, count, len); for(i = 0; i <= len; i++) { printf("%s" ,output[i]); } return 0; } よろしくお願いします。

  • C言語で分からないところがあるのですが

    すみません。C言語のポインタで分からないことがあって来ました。 ポインタの理屈は理解してはいるのですが、いざソースコードを書いてみようということになると全く手がつけられずにいます。 以下のソースコードですが、strlen()と同じ働きをする関数mystrlen()と、strcmp()と同じ働きをする関数mystrcmpを、ポインタを使って作成するものです。どこをどうすればいいのか教えてくださいませんか。 #include <stdio.h> int main(void) { char str1[80], str2[80]; int i, j; int len1, len2; printf("第1の文字列を入力してください: "); gets(str1); printf("第2の文字列を入力してください: "); gets(str2); /* * 文字列の長さを確認する */ /* NULL文字(文字列の最後)まで読み飛ばす */ for (len1 = 0; len1 < 80 && str1[len1] != '\0'; len1++) ; /* ループ終了後、len1 に文字列の長さが入っている */ if (len1 < 80) { printf("%s は %d 文字の長さです\n", str1, len1); } else { printf ("第1の文字列が80字以上あります\n"); } /* str2 についても同様 */ for (len2 = 0; len2 < 80 && str2[len2] != '\0'; len2++) ; if (len2 < 80) { printf("%s は %d 文字の長さです\n", str2, len2); } else { printf ("第2の文字列が80字以上あります\n"); } if (len1 < 80 && len2 < 80) { for (i = 0; i < 80 && str1[i] != '\0' && str2[i] != '\0' && str1[i] == str2[i]; i++) ; if (str1[i] == str2[i]) { /* 両者同時に == '\0' のはず*/ printf("文字列は等しい\n"); } else if (str1[i] < str2[i]) { /* str1[i] == '\0' のはず*/ printf("%s は %s より小さい\n", str1, str2); } else { /* str2[i] == '\0' のはず*/ printf("%s は %s より大きい\n", str1, str2); } } /* * 十分なスペースがあれば、str2をstr1の最後に連結する */ if (len1 + len2 < 80) { /* str1 の末尾を探す */ for (i = 0; str1[i] != '\0'; i++) ; /* ループを抜けた段階では i は len1 と同じはずなので、 上記のループを作らず、i の代わりに len1 を用いるのも可 */ /* それ以降に str2 の中身をコピーする */ for (j = 0; str2[j] != '\0'; j++) { str1[i+j] = str2[j]; } str1[i+j] = '\0'; printf("%s\n", str1); } else { printf ("文字列をつなげた長さが80字以上あります\n"); } /* * str2をstr1にコピーする */ if (len1 + len2 < 80) { for (i = 0; str1[i] != '\0'; i++) { str1[i] = str2[i]; } str1[i] = '\0'; printf("%s %s\n", str1, str2); } return 0; }

  • c言語の文字列の逆順のプログラムがわかりません

    文字列を逆順して出力するプログラミングがわかりません。 #include <stdio.h> #include <string.h> void reverse(char *moji, char *gyaku); int main(void) { char x[30]; char y[30]; puts("文字を入力してください。\n"); scanf("%s", x); reverse(x, y); printf("逆順すると%sです。\n", y); return (0); } void reverse(char *moji, char *gyaku) { int i, len; len = strlen(moji); gyaku = moji + len - 1; for(i = 0; i < len; i ++){ putchar((int)*gyaku); gyaku--; } } 理想とする実行結果は 文字を入力してください。 abcdefg 逆順するとgfedcbaです。 なんですが、 上記のソースを実行すると 文字を入力してください。 abcdefg gfedcba逆順すると(謎の漢字)です。 となります。 どこがおかしいんでしょうか? よろしくおねがいします。

  • EAccessViolationクラス例外

    WindowsXPでBCB5を使用しています。 柴田望洋氏著、新版明解C++入門編の演習8-14ですが 「文字列sの文字の並びを反転する関数str_rvsを作成せよ。 char* str_rvs(char* s); たとえば、文字列sが"abc"であれば、その文字列を"cba"に更新する。受け取ったsの値をそのまま返却すること。」 と言う問題で、下記の様に作成したんですが、 char* s="a"、または"ab"、または"abc"とすると正常に終了しますが "abcd"とすると、 文字列[abcd]を反転します。 dcba 文字列[dcba]を反転します。 abcd が繰り返された後、「EAccessViolationクラスの例外を生成しました。~」が表示されて停止します。 s="abcde"とすると 文字列[abcde]を反転します。 edcba と1回表示されて、同様のエラーが発生しますが、何が悪いのかわかりません。ご教授願います。 //--------------------- #include <iostream> #include <cstring> using namespace std; char* str_rvs(char* s){ int len=strlen(s); char* tmp; for(int i=0;i<len;i++) *(tmp+i)=*(s+len-1-i); *(tmp+len)=NULL; for(int i=0;i<len;i++) *(s+i)=*(tmp+i); return s; } int main(){ char* s="abcd"; cout << "文字列[" << s << "]を反転します。\n"; cout << str_rvs(s) << '\n'; //getchar(); }

  • Cの文字列関連の質問です。よろしくお願いします。

    Cの文字列関連の質問です。よろしくお願いします。 『読み込んだ文字列がナル文字を含めて15文字以下であれば、その文字列をそのまま格納し、そうでない場合、読み込んだ文字列の先頭14文字とナル文字を格納する』 という条件を満たすプログラムを作成しました。 #include <stdlib.h> #include <string.h> #include <stdio.h> int main(void) { int num; char (*p)[15]; printf("文字列の個数: "); scanf("%d", &num); p = (char (*)[15])malloc(num * 15); if (p == NULL) puts("記憶域の確保に失敗"); else { int i; char tmp[100]; /* 書込み */ for (i = 0; i < num; i++) { printf("p[%d]: ", i); scanf("%s", tmp); sprintf(p[i], "%.14s", tmp); } /* 表示 */ for (i = 0; i < num; i++) printf("p[%d]: %s\n", i, p[i]); free(p); } return 0; } この場合は、ちゃんと条件を満たした結果が出ました。 ここで24行目の『sprintf(p[i], "%.14s", tmp);』を『strncpy(p[i], tmp, 14);』に変更する明らかに結果がおかしくなります。 strncpyを使った方法に変更する場合、どのように修正を行えばいいのでしょうか? 長々と書いてしまいましたが、よろしくお願い致します。

  • C言語

    文字列を逆順にするプログラムを考えているのですが分かりません。(例)qwerならrewqです。入力終了は、EOFです。考えたのですが、分かりません。(コンパイルエラーです。)教えてください。宜しくお願いします。#include <stdio.h> unsigned str_length(const char str[]) { unsigned len=0; while (str[len]) len++; return (len); } void put_rstring(const char str[]) { unsigned i = str_length(str): while (i-- >0) putchar(str[i]); } int main(void) { char str[30]; int ch; printf("文字列を入力\n"); /* ----この文字列を入力したあとに、Ctrl+Zを押すと、逆から表示               で反対から、文字列が表示----*/ while (1) { ch=getchar(); if (ch==EOF) break; } printf("逆から表示"); put_rstring(str); puts("です。"); return(0); }

  • C言語の課題で困っています;

    C言語の課題で困ってます; 学校の課題で、キーボードから文字を入力する(最大80文字)。入力された文字列と、入力した文字列を逆順にした文字列を表示する。(malloc,freeを使って作成して下さい) ヒントで #invlude <stdio.h> void main(void){ char *buf; //入力文字列用 char *seq; //入力文字列用コピー用 char *rev; //逆順文字列用 int lec, i; buf =(char*)malloc(81); printf("文字列を入力:"); scanf("%s"buf ); for(i = 0; buf[i] ??? '\0'; i++){ } Ien = i; /* lenに文字列の長さが入る */ seq = ???(??? + 1); /* len+1文字文確保*/ for(i = 0; ???; i++){ seq[0] = buf[0]; } free(buf); rey = ???(len + 1); for(i = 0; < len; i++){ rev[len - i - 1] = seq[i]; } ren[i] ~ '\0'; printd("入力文字列 : %s\n",sep); でたんですが、全然分からなくて足りない部分の答えを教えてもらえると助かります;

  • セグメンテーション違反について教えてください。

    2つの文字列s、tを入力して 、sの中からtを検索し、一致したらsからtを削除したものを結果に出すという問題です。たとえば、s = a v a b c a 、t = a b c とすると、sからa b cが削除され、a v aと結果が表示されます。 ちなみに条件として、s、tとも配列の大きさが80となっており、出力用の文字列out[ ]も同様です。 また、文字列の入力は50字に制限されています。 ロジックを何とかつかんだ後、以下のようにコードで書いたのですが、セグメンテーション違反になってしまいます。 (1)まず、2行何か書かなければ「文字列を入力して下さい」が表示されません。 (2)「文字列を入力して下さい」「削除する文字列を入力したください」は表示されますが、その後の「削除後の文字列」とその結果が表示されません。 (3)その代わり、セグメンテーション違反が出ます。 たとえば、こんな感じで表示されてしまいました。 /************************************************/ 12 12 文字列を入力して下さい。(50字) :asd 削除する文字列を入力して下さい。(削除) :a セグメンテーション違反です /************************************************/ このとき、どこを直せばいいのでしょうか? 1 #include <stdio.h> 2 #include <string.h> 3 4 #define NULLB '0' /* 入力制限 */ 5 6 int main(int argc , char *argv[]) 7 { 8 /*********各変数の宣言*********/ 9 char s[80] ; 10 char t[80] ; 11 char out[80] ; 12 int s_len ; 13 int t_len ; 14 int out_len ; 15 int s_index ; 16 int t_index ; 17 int out_index ; 18 19 /******************************/ 20 21 fgets(s , 50 , stdin) ; 22 fgets(t , 80 , stdin) ; 23 24 25 printf("文字列を入力して下さい。(50字) :" ) ; 26 scanf("%s",&s) ; 27 s_len = strlen(s) ; 28 29 30 printf("削除する文字列を入力して下さい。(削除) :") ; 31 scanf(" %s",&t) ; 32 t_len = strlen(t) ; 33 34 35 /********各変数の初期化********/ 36 memset(s , '\0' , sizeof(int) *80) ; 37 memset(t , '\0' , sizeof(int) *80) ; 38 memset(out , '\0' , sizeof(int) *80) ; 39 s_index = 0 ; 40 t_index = 0 ; 41 out_index = 0 ; 42 43 /******************************/ 44 45 if( s_len >= t_len) 46 { 47 48 /********外側のループ********/ 49 while(s_index < s_len) 50 { 51 /********内側のループ********/ 52 while(t_index < t_len) 53 { 54 if( (s_len - s_index) >= t_len) 55 { 56 if( s[s_index + t_index] == t[t_index]) 57 { 58 if(t_len - t_index ==1) 59 { 60 s_index += t_len ; 61 } 62 else 63 { 64 continue ; 65 } 66 t_index ++ ; 67 } 68 else 69 { 70 out[out_index] = s[s_index] ; 71 out_index++ ; 72 s_index++ ; 73 74 break ; 75 } 76 } 77 else 78 { 79 strncpy(out, s , (s_len-s_index + 1 )) ; 80 } 81 } 82 /****************************/ 83 } 84 /****************************/ 85 } 86 else 87 { 88 strcpy( out, s) ; 89 } 90 91 printf("\n削除後の文字列: %s": ); 92 93 return 0 ; 94 }

  • 文字を反転させる。

    以下の手順に従ってプログラムを作成せよ.適宜printf を利用して,入力支援(「文字列を入 力して下さい」などの画面表示)を行うこと. (1) キーボードから文字列を入力し,文字配列s[64] に格納する. (2) 文字配列s[64] に格納されている文字列を逆順にしてt[64] に格納する(配列全部を逆 順にするのではなく,NULL 文字までの要素を逆順にする). (3) t[64] を画面表示する. ポインタ使用不可、ヘッダファイル<stdio.h>だけ 入力された文字を反転させるということでしょうか?? #include <stdio.h> int main(void){ int i; char s[256]; char t[256]; printf("文字列を入力:"); scanf("%s" , s); for ( i = 0; i < '\n'; i++ ){ t[i] = s[i]; } printf("文字列の逆順は%s",t); getchar(); getchar(); return(0); } これだとただ入力された文字を出力するだけになってしまいますよね・・・・。どうすればいいのでしょうか?

  • 作ったプログラミングC何だけど、評価していただけませんが?不足があれば、教えてください!

    文字列「abc」の各アルファベットを1文字ずらすと文字列「bcd 」になり、 文字列「nisidate」の各アルファベットを2文字ずらすと文字 列「pkukfcvg」となる。さらに、 文字列「kibishii」の各アルファベットを2文字ずらすと文字 列「mkdkujkk」となる。 このような、任意の文字列の各要素を任意の文字数ずらすプロ グラムを作成する、なお、zを1文字ずらしたとき のアルファベットはaとする。 #include <stdio.h> #include <string.h> int main(void) { char str[27]="abcdefghijklmnopqrstuvwxyz",str1[50], str2[50]; int x,i,j,len; printf("文字列を入力---> "); scanf("%s", str1); printf("何文字ずらすかを入力---> "); scanf("%d",&x); len=strlen(str1); for(i=0;i<len;i++) { for(j=0;j<27;j++) { if(str1[i]=='z') { str2[i]=str[x-1]; } if(!(str1[i]=='z')) { if(str1[i]==str[j]) { str2[i]=str[j+x]; } } } } printf("%d文字ずらした文字列は%sです\n", x, str2); return 0; } よろしくお願いします!!

専門家に質問してみよう