質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

Q&A

解決済

5回答

828閲覧

ctypeを使わずに大文字小文字を相互に交換したいです

sansan1

総合スコア7

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

0グッド

1クリップ

投稿2020/01/31 05:57

課題で条件としてchangeS_letterの型はvoidにすることと、stdio.hのみをインクルードすることが指定されています。

ネットでctypeを使わないで変換する方法を見つけ、それを参考にしてやってみたのですが、変換がされずにそのまま出力されてしまいます。あと、フフフという文字も出てきてしまいます。

C

1#include<stdio.h> 2 3void changeS_letter(char *tmp, const char *str) 4{ 5 while (*tmp == *str) { 6 if ('a' <= *str && *str <= 'z') { 7 *tmp = *str - ('a' - 'A'); 8 str++; 9 tmp++; 10 } 11 12 else { 13 *tmp = *str + ('a' - 'A'); 14 str++; 15 tmp++; 16 } 17 } 18} 19 20int main(void) 21{ 22 char str[30]; 23 char tmp[30]; 24 25 printf("Please input a string\n"); 26 scanf("%s", str); 27 28 printf("result\n"); 29 30 changeS_letter(tmp, str); 31 32 printf("%s\n", tmp); 33} 34

こちらが参考にしていただいたものです---------------------------

C

1#include <stdio.h> 2 3void upperstring(char*, const char*); 4void lowerstring(char*, const char*); 5char upper(char); 6char lower(char); 7 8void upperstring(char *out, const char *in){ 9 int i; 10 11 i = 0; 12 while(in[i] != '\0'){ 13 out[i] = upper(in[i]); 14 i++; 15 } 16} 17 18void lowerstring(char *out, const char *in){ 19 int i; 20 21 i = 0; 22 while(in[i] != '\0'){ 23 out[i] = lower(in[i]); 24 i++; 25 } 26} 27 28char upper(char c){ 29 if('a' <= c && c <= 'z'){ 30 c = c - ('a' - 'A'); 31 } 32 return c; 33} 34 35char lower(char c){ 36 if('A' <= c && c <= 'Z'){ 37 c = c + ('a' - 'A'); 38 } 39 return c; 40} 41 42int main(void){ 43 char s[20]; 44 45 upperstring(s, "I am a CAT"); 46 printf("%s\n", s); 47 48 lowerstring(s, "I am a CAT"); 49 printf("%s\n", s); 50 51 return 0; 52}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答5

0

C の言語仕様としては文字コードに関する定めは処理系定義です。 最新の規格ではユニコードに関する記述が追加されていますが、通常の文字列にどのような文字コード体系を用いるかは環境によります。 実際に EBCDIC などを採用している環境は存在します。

現在の一般的なアーキテクチャはアスキーコード、またはアスキーコードを基礎にした文字コード体系を採用している場合は多いですが、 C の言語仕様の範囲内でということであれば ctype を使わずにということは不可能です。

ここではアスキーコードを前提にしているという想定でよろしいですね?


正直に言って全体的に不自然なのでどこが間違っているとは指摘しづらいのですが……。

*tmp == *str

本来なら、文字列をたどる処理を終了する条件をかくべきところです。

*tmp はこれから入れるべきところであって、まだ意味のあるデータは入っていません。 それと *str を比較しても意味のある比較にはなりません。

else

入力が小文字でなければ大文字であるというわけではありません。 記号や数値などもあります。

  • 大文字の場合
  • 小文字の場合
  • それ以外

という三種類に分岐する必要があります。

終端文字

文字列の最後の要素はゼロを入れて終わりを示すというルールがあります。

最初に示した処理の終了条件としては「*str がゼロになるまで」という形で文字列を最後までたどることが出来ます。

そして tmp の最後にもゼロを入れなければなりません。

投稿2020/01/31 06:26

SaitoAtsushi

総合スコア5444

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sansan1

2020/01/31 06:55

細かく丁寧にありがとうございます
guest

0

ct.c

c

1#include<stdio.h> 2 3const char * UPPERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 4const char * LOWERS = "abcdefghijklmnopqrstuvwxyz"; 5 6int my_index(const char *str, const char c) { 7 if (str) { 8 for (const char * cp = str; *cp; cp++) { 9 if (c == *cp) { 10 return cp - str; 11 } 12 } 13 } 14 return -1; 15} 16 17char change_c(const char c) { 18 int idx; 19 if ((idx = my_index(UPPERS, c)) != -1) { 20 return LOWERS[idx]; 21 } else if ((idx = my_index(LOWERS, c)) != -1) { 22 return UPPERS[idx]; 23 } 24 return c; 25} 26 27void changeS_letter(char *dest, const int dest_size, const char *src) { 28 if (dest_size < 1 || dest == NULL || src == NULL) { 29 return; 30 } 31 32 for (int i = 0; i < dest_size; i++) { 33 dest[i] = change_c(src[i]); 34 if (dest[i] == '\0') { 35 return; 36 } 37 } 38 dest[dest_size - 1] = '\0'; 39} 40 41int main(void) { 42 char s[20]; 43 changeS_letter(s, 20, "I am a cat,(笑)"); 44 printf("%s\n", s); 45 46 47 changeS_letter(s, 20, s); 48 printf("%s\n", s); 49 50 changeS_letter(s, 20, ""); 51 printf("%s\n", s); 52 53 changeS_letter(s, 20, NULL); 54 printf("%s\n", s); 55 56 char* dest = "abc ABC"; 57 changeS_letter(s, 3, dest); 58 printf("%s\n", s); 59 60 changeS_letter(s, 0, dest); 61 printf("%s\n", s); 62 63 changeS_letter(NULL, 0, dest); 64 65 return 0; 66}

実行例

イメージ説明

もっとコードを短くすることは可能とおもいます。
まずは、"動作する事" と "不正なメモリーアクセスを起こさない事" を目指して書いてみました。

投稿2020/02/01 01:34

katoy

総合スコア22324

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

小文字を大文字に変換するのはいいのですが、
小文字でない文字すべてを変換するのはいけませんね。
abc123XYZ が ABCQRSxyz になってしまいます。
この問題を修正ましょう。

文字コードが ASCII またはその拡張なら、次のようにも書けます。

C

1void changeS_letter(char *t, const char *s) 2{ 3 do { 4 *t++ = *s ^ (*s - 'A' < 26u || *s - 'a' < 26u) << 5; 5 } while (*s++); 6}

追記
英字だけで呼び出されることが分かっていればこれで十分。

C

1#include <stdio.h> 2 3void changeS_letter(char *t, const char *s) 4{ 5 do *t++ = 'A' ^ 'a' ^ *s; while (*s++); 6} 7 8int main(void) 9{ 10 char str[30]; 11 changeS_letter(str, "ABCxyz"); 12 puts(str); 13}

文字コードは ASCII でも EBCDIC でもどちらでも OK。

投稿2020/01/31 07:51

編集2020/02/01 04:38
kazuma-s

総合スコア8224

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sansan1

2020/01/31 08:33

はしょってしまいましたが、この関数の前に数字と英字を分ける関数があります。 すみません、そこも書いておけば良かったですね
guest

0

自己解決

・(*str != '\0')に変更
・*tmp = '\0'を追加

C

1#include<stdio.h> 2 3void changeS_letter(char *tmp, const char *str) 4{ 5 while (*str != '\0') { 6 if ('a' <= *str && *str <= 'z') { 7 *tmp = *str - ('a' - 'A'); 8 str++; 9 tmp++; 10 } 11 12 else{ 13 *tmp = *str + ('a' - 'A'); 14 str++; 15 tmp++; 16 } 17 } 18 *tmp = '\0'; 19} 20 21int main(void) 22{ 23 char str[30]; 24 char tmp[30]; 25 26 printf("Please input a string\n"); 27 scanf("%s", str); 28 29 printf("result\n"); 30 31 changeS_letter(tmp, str); 32 33 printf("%s\n", tmp); 34}

投稿2020/01/31 06:54

sansan1

総合スコア7

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

  1. while (*tmp == *str) { が意味不明です
  2. tmpに文字列終端の'\0'が代入されてません。
  3. tmp[]は初期化されていません

まずはこれらをどーにかしましょう

投稿2020/01/31 06:17

y_waiwai

総合スコア87774

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問