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

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

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

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

Q&A

解決済

2回答

1110閲覧

文字列の判定や変換など

Merrifield

総合スコア31

C

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

0グッド

0クリップ

投稿2020/09/01 01:50

編集2020/09/01 04:04

solve("coDe") = "code". 小文字>大文字の場合 すべて大文字に
solve("CODe") = "CODE". 大文字>小文字の場合 すべて小文字に
solve("coDE") = "code". 大文字=小文字の場合 すべて小文字に

このような関数を作りたいと思っています。下のようにコードを書いたのですが、おかしなところがあれば教えてください。islowerやisupperのような単語が出てきてエラーメッセージの意味がよく分からないので、どういう意味なのか教えていただけないでしょうか。

codewarsでの問題なのでリンク貼っておきます
https://www.codewars.com/kata/5b180e9fedaa564a7000009a/train/c

c

1#include <ctype.h> // toupper, tolower 2#include <string.h> // strlen 3#include <stdlib.h> //malloc 4 5char *solve(const char *str) 6{ 7 int lowercase = 0; 8 int uppercase = 0; 9 int m = strlen(str); 10 11 char *result = malloc(m); 12 13 for(int n = 0; n < m; n++) 14 { 15 if((str[n]>= 'a') && (str[n]<='z')) 16 { 17 lowercase++; 18 } 19 else if((str[n]>= 'A') && (str[n]<='Z')) 20 { 21 uppercase++; 22 } 23 } 24 25 if(uppercase > lowercase) 26 { 27 28 for(int n = 0; n < m; n++) 29 { 30 result[n] = toupper(str[n]); 31 } 32 } 33 else 34 { 35 for(int n = 0; n < m; n++) 36 { 37 result[n] = tolower(str[n]); 38 } 39 } 40 41 return result; 42}

エラー

fixture.c:33:18: warning: implicitly declaring library function 'isupper' with type 'int (int)' [-Wimplicit-function-declaration] count += isupper(*pc) ? +1 : (islower(*pc) ? -1 : 0); ^ fixture.c:33:18: note: include the header <ctype.h> or explicitly provide a declaration for 'isupper' fixture.c:33:39: warning: implicitly declaring library function 'islower' with type 'int (int)' [-Wimplicit-function-declaration] count += isupper(*pc) ? +1 : (islower(*pc) ? -1 : 0); ^ fixture.c:33:39: note: include the header <ctype.h> or explicitly provide a declaration for 'islower' fixture.c:34:15: warning: implicit declaration of function 'strdup' is invalid in C99 [-Wimplicit-function-declaration] char *s = strdup(str); ^ fixture.c:34:11: warning: incompatible integer to pointer conversion initializing 'char *' with an expression of type 'int' [-Wint-conversion] char *s = strdup(str); ^ ~~~~~~~~~~~ fixture.c:36:27: warning: implicitly declaring library function 'toupper' with type 'int (int)' [-Wimplicit-function-declaration] *pc = count > 0 ? toupper(*pc) : tolower(*pc); ^ fixture.c:36:27: note: include the header <ctype.h> or explicitly provide a declaration for 'toupper' fixture.c:36:42: warning: implicitly declaring library function 'tolower' with type 'int (int)' [-Wimplicit-function-declaration] *pc = count > 0 ? toupper(*pc) : tolower(*pc); ^ fixture.c:36:42: note: include the header <ctype.h> or explicitly provide a declaration for 'tolower' fixture.c:42:11: warning: implicit declaration of function 'time' is invalid in C99 [-Wimplicit-function-declaration] srand(time(0)); ^ 7 warnings generated.

関数を
'EzZgfiAafUSHJrqYaelIMBcScjeGChmgiNOoVRQa'でテストすると
"ezzgfiaafushjrqyaelimbcscjegchmginoovrqaQ"のようになります。

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

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

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

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

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

dodox86

2020/09/01 02:15

エラーメッセージと提示されているコードが一致していないように思います。(実際、提示されているコードはmain()が無いので、gccでコンパイルのみ行うことはできます。警告もエラーも出ません) エラーメッセージで出ているコードが謎なので、コンパイルしているコード全部を載せてみてはいかがでしょうか。
Merrifield

2020/09/01 02:20

codewarsというサイト上でコードを書いていて、コードはこれが全てです。
dodox86

2020/09/01 02:24

ああ、なるほど。solveと言う決まった関数で定義すると実行してくれる課題(問題)っぽいですね。良くみるとエラーでなくワーニング(警告)ですね。
Merrifield

2020/09/01 02:27

質問に書いておくべきだしたね、失礼しました。
Zuishin

2020/09/01 03:29

codewars のどの問題かリンクを張ってください。
guest

回答2

0

fixture.c:33:18: warning: implicitly declaring library function 'isupper' with type 'int (int)' [-Wimplicit-function-declaration]

count += isupper(*pc) ? +1 : (islower(*pc) ? -1 : 0); ^

fixture.c:33:18: note: include the header <ctype.h> or explicitly provide a declaration for 'isupper'

implicitly(暗黙の) declaring(宣言) library(ライブラリ) function(関数)
'isupper' with type(型) 'int (int)'

なので、
「ライブラリー関数のisupperが、int(int)型として、暗黙の宣言がなされました」
ぐらいの意味です。

なんで使ってもいないisupperが?というのは、fixture.cの33行目で使っているとの事なので確認してみてください。

対応策もメッセージに書かれていて、
note: include the header <ctype.h>
なので、
#include <ctype.h>
として、ctype.hをインクルードすればよいらしいです。

投稿2020/09/01 02:46

amiya

総合スコア1218

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

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

Merrifield

2020/09/01 02:59

#include <ctype.h>は書いてると思うのですが、なにが違うのでしょうか?
amiya

2020/09/01 03:11

ああ。ありましたね。すみません。 おそらく、isupperを使っているのされている、fixture.c のほうに、という事だと思います。
rubato6809

2020/09/01 14:51

fixture.c というファイル名がナゾ。どこにこのファイル名があるのだろうか? 質問者が書いたコードのファイルが fixture.c なら理解できるのだけど、 そのページをみたら solution.c というファイル名としてコンパイルされるようなんだけど。
guest

0

ベストアンサー

int m = strlen(str);

char *result = malloc(m);

これまずいですね
C言語においては、文字列というのは、終端に'\0'をくっつけた文字配列です。
ですんで、文字数+1の領域を確保する必要があります

#どこでfreeすんねん、というのは横に置いといて。


warning: implicitly declaring library function 'isupper' with type 'int (int)'

isupperの関数定義がないので、intを返す関数として解釈しますで、というワーニングです。
きちんとプロトタイプ宣言しておく、あるいは、それを記述したヘッダファイルをインクルードしましょう

投稿2020/09/01 02:03

編集2020/09/01 02:10
y_waiwai

総合スコア87774

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

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

Merrifield

2020/09/01 02:11

strの大きさを求めれば、\nを含めた大きさになると思っていたのですがそうではないのでしょうか? freeは必要だというのはさすがに知っていますが、今回はcodewarsというサイト上で問題を解いているので、ほかの回答者を見る限りfreeはやっていない(たぶんする必要がない)ので書いていないです。
y_waiwai

2020/09/01 02:15

そうではないです。そこらへん注意しましょう また、結果の文字列の終端に'\0'を入れてないのがおかしくなってる原因です まあ、プログラムが終了するときには一切合切開放されますんで、メモリ不足にならない限りはfreeしなくて構わないという考え方もありますね
Merrifield

2020/09/01 02:22

そうだったのですね。ありがとうございます。 freeに関して、終了すると解放されるのだから、必要以上にfreeを書く必要はないというのは、聞いたことがありますね。
ttyp03

2020/09/01 02:23

isupperなんて関数使ってないのになんでエラーメッセージに出てくるの?って質問じゃないんでしょうか?
dodox86

2020/09/01 02:36

> freeに関して、終了すると解放されるのだから、必要以上にfreeを書く必要はないというのは、聞いたことがありますね。 心がけとして、自分でmalloc()系を呼んだら自分でfreeしなければいけません。そうでないと、長時間稼働するような常駐プログラムではメモリリークとなります。今回の質問については、char *solve(const char *str)と言う関数名とシグネチャで内容を定義し、呼び出し側でfree()される課題(問題)なのではないかな、と思います。(そうでないならばご指摘ください)
dodox86

2020/09/01 02:38

何で自分が書いたコード以外で警告が出るのか、と言えば、呼び出し側(codewarsのシステムが用意したmain側)のテストコードで出てしまっているのではないでしょうか。
Merrifield

2020/09/01 02:57

>>心がけとして、自分でmalloc()系を呼んだら自分でfreeしなければいけません。 そうですね、自分の場合、まだ詳しくないのでmallocしたらfreeを必ずつけるという心掛けはしたいと思います。 二つ目の文の意味がちょっと分からなかったのですが、質問文にかいてある例のように、引数として与えられた値(今回の場合は文字列)に応じて適切な戻り値として返せるかというのを、サイト側が判定します。引数に様々なパターンの値をいれてテストし、コードが合っているかをサイト側が確認するしているだけなので、自分でfreeを書いたりする必要はないと思います。別の問題で他の回答者のコードでもfreeは書いていなかったので。ずれた回答になっていたらすみません。
Merrifield

2020/09/01 03:00

サイト側がどういう風にやっているのか分かっていないのですが、そっちのほうのコードのエラーとして、使用していない単語など出ているということなんですね。
dodox86

2020/09/01 03:11

> 二つ目の文の意味がちょっと分からなかったのですが、 まぁ私もcodewarsのシステムを知っている訳ではないのでほとんど推測でのコメントなのですが、malloc()やfree()を質問者さんが意識していず、また問題にその辺りのことが書いていないのであれば、プログラムはすぐに終わるのであろうし、とにかく返り値でchar* で返すことさえ満たしていれば良いのだと思います。例えばmallocを使わず、 char sbuf[充分なサイズのグローバルな配列]; char *solve(const char *str) { // sbufに対する操作色々 return sbuf; } とかでも良いのでは、と。 > そっちのほうのコードのエラーとして、使用していない単語など出ているということなんですね。 これはあくまで私の推測ですが。たぶん、そうです。回答とは離れてきているので、この辺で。
Merrifield

2020/09/01 04:21

終端文字がなかったことが問題だったようです。ありがとうございました。
rubato6809

2020/09/01 14:55

#どこでfreeすんねん 皆さん、そのページ見てないの? void do_test(const char *str, const char *expected) { char *actual = solve(str); // 途中省略 free(actual); となってるので全く問題ありません。
dodox86

2020/09/01 15:51

>@rubato6809さん > 皆さん、そのページ見てないの? そのページが明らかになったのはコメントがやり取りされてずいぶん後、だったのです。
rubato6809

2020/09/01 22:14

そういうことでしたか。了解です。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問