こんにちは。
C言語で分からないことがあり、質問させていただきました。
学校で、文字列の取り扱いを習いました。
そこで質問なんですが、以下のソースコードをstrcpy , strcat , strcmp , strlen を使わずに書くことってできないですか?
先生に質問したところ、ポインタとかいうのを使うのだそうですが、それを使わずに書くことってできるんですか?もしよろしければお願いします。
以下のプログラムですが、ユーザーから2つの文字列を受けて、そこから4つの文字列関数を使ってみましょう、というやつです。実行結果も貼っておきますね。
#include <string.h>
#include <stdio.h>
int main(void)
{
char str1[80], str2[80];
int i;
printf("INPUT 1st word-line. : ");
gets(str1);
printf("INPUT 2nd word-line. : ");
gets(str2);
/*文字列(word-line)の長さを確認します。*/
printf("%s is %d moji long.\n", str1, strlen(str1));
printf("%s is %d moji long.\n", str2, strlen(str2));
/*文字列を比較します。*/
i = strcmp(str1, str2);
if (!i)
printf("two word-lines are same length.\n");
else if (i < 0)
printf("%s is smaller than %s.\n", str1, str2);
else
printf("%s is bigger than %s.\n", str1, str2);
/*十分なスペースがあるのなら、str2をstr1の最後に結合させます。*/
if((strlen(str1) + strlen(str2)) < 80 ){
strcat(str1, str2);
printf("%s\n", str1);
}
/*str2をstr1にコピーする*/
strcpy(str1, str2);
printf("%s %s\n", str1, str2);
No.1
- 回答日時:
>i = strcmp(str1, str2);
>if (!i)
>printf("two word-lines are same length.\n");
strcmp()の戻り値で、2つの文字列が同じ長さであることは判定「できません」。
考え直しましょう。
No.3ベストアンサー
- 回答日時:
>以下のソースコードをstrcpy , strcat , strcmp , strlen を使わずに書く
>ポインタとかいうのを使うのだそうですが、それを使わずに書くことってできるんですか?
授業では扱われない「裏道」ってことですね。愚直なまでに・・↓。
ただ、
uni is bigger than fortissimo. とはならず
uni is smaller than fortissimo. となってしまいますが・・。
#include <stdio.h>
int LengthGet( char str[] )
{
int i;
for( i = 0; i < 80; i++ ){
if( '\0' == str[ i ] ) return( i );
}
return( 0 );
}
int main( void )
{
char str1[80], str2[80];
int iLen1, iLen2, i, j;
printf( "INPUT 1st word-line. : " );
gets( str1 );
printf( "INPUT 2nd word-line. : " );
gets( str2 );
iLen1 = LengthGet( str1 );
iLen2 = LengthGet( str2 );
printf( "%s is %d moji long.\n", str1, iLen1 );
printf( "%s is %d moji long.\n", str2, iLen2 );
if( iLen1 == iLen2 ) printf( "two word-lines are same length.\n" );
if( iLen1 < iLen2 ) printf( "%s is smaller than %s.\n", str1, str2 );
if( iLen1 > iLen2 ) printf( "%s is bigger than %s.\n", str1, str2 );
if( ( iLen1 + iLen2 ) < 80 ){
for( i = 0; i < iLen2; i++ ) str1[ iLen1++ ] = str2[ i ];
str1[ iLen1 ] = '\0';
printf( "%s\n", str1 );
}
for( j = 0, i = 0; i < iLen2; i++ ) str1[ j++ ] = str2[ i ];
str1[ j ] = '\0';
printf( "%s %s\n", str1, str2 );
return( 0 );
}
注:インデントに全角空白を用いています。コピペ後、タブに一括変換して下さい。
No.4
- 回答日時:
#3さんの sprintf() バージョンです。
#include <string.h>
#include <stdio.h>
#define SIZE 80
int _strlen(char buf[]);
int main(void)
{
char str1[SIZE], str2[SIZE];
int i, _strlen1,_strlen2;
printf("INPUT 1st word-line. : ");
gets(str1);
printf("INPUT 2nd word-line. : ");
gets(str2);
/*文字列(word-line)の長さを確認します。*/
printf("%s is %d moji long.\n", str1, _strlen1=_strlen(str1));
printf("%s is %d moji long.\n", str2, _strlen2=_strlen(str2));
/*文字列を比較します。*/
i = _strlen1 - _strlen2;
if (i==0)
printf("two word-lines are same length.\n");
else if (i < 0)
printf("%s is smaller than %s.\n", str1, str2);
else
printf("%s is bigger than %s.\n", str1, str2);
/*十分なスペースがあるのなら、str2をstr1の最後に結合させます。*/
if((_strlen1 + _strlen2) < SIZE ){
sprintf(str1+_strlen1, "%s", str2);
printf("%s\n", str1);
}
/*str2をstr1にコピーする*/
sprintf(str1, "%s", str2);
printf("%s %s\n", str1, str2);
return 0;
}
int _strlen(char buf[])
{
int i=0;
while(buf[i]) i++;
return i;
}
----- 実行結果 -----
INPUT 1st word-line. : uni
INPUT 2nd word-line. : fortissimo
uni is 3 moji long.
fortissimo is 10 moji long.
uni is smaller than fortissimo.
unifortissimo
fortissimo fortissimo
No.5
- 回答日時:
int mystrlen(char str[])
{
int i;
for (i=0 ; str[i] ; i++) {
}
return i;
}
str は char の配列のように見えますが、実際には char へのポインタです。
int mystrlen(char *str) と書いても全く同じ。
関数 mystrlen に配列を渡そうとすると、実際にはその最初の要素へのポインタが渡ります。
ちょっとややこしいですが、C で文字列を取り扱おうとすると、現実的にポインタの使用は避けられないのです。
No.6
- 回答日時:
#4です。
>int mystrlen(char *str) と書いても全く同じ。
>関数 mystrlen に配列を渡そうとすると、実際にはその最初の要素へのポインタが渡ります。
関数 mystrlen に配列を渡そうとすると、その最初の要素へのアドレスが渡ります。
int mystrlen(char *str) と書くとポインターにその最初の要素へのアドレスが渡ります。
結果として同じに見えるので、注意が必要です。
http://www.nurs.or.jp/~sug/soft/tora/tora9.htm
No.7
- 回答日時:
#6 について
すみません。
指摘内容がどうも理解できません。
何と何が同じに「見える」のか?
「結果的に」「見える」ということは、実は違うということなのか?
注意が必要とは、何か問題が起こるということなのか?
# 参考 URL に示されたような、
# 配列とポインタの違いについては理解しております。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# バイナリファイルをコピーするのにかかる時間を測りたいのですが実行するとFatel error:gli 2 2022/11/03 01:10
- Visual Basic(VBA) select caseの入れ子 3 2023/03/08 18:48
- Visual Basic(VBA) VBAで時間(00:00形式)を積算(足し算)したい 1 2022/11/15 17:04
- Visual Basic(VBA) countifsについての質問 3 2023/03/08 13:45
- Visual Basic(VBA) VBAで最新のデータを別シートに転記する方法をお教えください。 3 2022/04/07 19:20
- Visual Basic(VBA) Worksheet_Change 4 2023/03/12 21:54
- Visual Basic(VBA) 2つのシートの任意のセルの番号が一致したら、一致した行をコピーする VBA 2 2023/06/19 20:48
- その他(自然科学) 信頼度がR1、R2の機器を並列に接続した場合、システム全体の信頼度はどれか。答え1-(R1)(1- 2 2023/01/15 21:45
- Visual Basic(VBA) ワークブック内すべて検索 2 2022/12/20 20:13
- 電車・路線・地下鉄 初台→新宿3→代官山(7.6km)IC528円 笹塚→新宿3→中目黒(10.2Km)IC433円なぜ 5 2022/11/24 09:26
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Enterキーを押されたら次の処理...
-
【C言語】全角文字の配列を、全...
-
プログラミングの授業の課題です
-
C言語のプログラムで、途中で止...
-
C言語でファイルから複素数の値...
-
終了条件Ctrl+zについて,結果表...
-
空白を含んだ文字列がうまく格...
-
printf による16進表示について
-
警告 W8075 問題のあるポインタ...
-
VC++でSQLへSELECT文を送ったの...
-
C言語でのCSVファイルの読み出...
-
へんな現象
-
#define _CRT_SECURE_NO_WARNIN...
-
マイナスからプラスへ転じた時...
-
*をユーザーが入力した数字の数...
-
2÷3などの余りについて
-
10個出力で改行したいのですが...
-
C言語での奇数の和
-
複数桁10進数の*桁目だけを抽出...
-
正負を反転させて出力するプロ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Enterキーを押されたら次の処理...
-
C言語で複数列のデータを1列の...
-
#defineが使用するメモリ領域に...
-
printf による16進表示について
-
空白を含んだ文字列がうまく格...
-
C言語のプログラムで、途中で止...
-
プログラミングの授業の課題です
-
char型2つを結合し、short型に...
-
C言語でのCSVファイルの読み出...
-
矢印キーを押下してコンソール...
-
【C言語】全角文字の配列を、全...
-
エラーについて質問です。
-
リストの作成と出力(C言語)
-
バイナリファイル(画像)のよみ...
-
[C]セグメンテーションエラー:...
-
WinInetのInternetOpenUrl関数...
-
c言語で文書を読み込み、単語の...
-
VC++でSQLへSELECT文を送ったの...
-
受信データから必要な部分のみ...
-
reallocでエラー
おすすめ情報