C言語 コマンド・パラメータ

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
かずま

C言語 コマンド・パラメータ

#1

投稿記事 by かずま » 9年前

こんにちわ!
C言語勉強中の者です。

C言語で、argvを使用してコマンド・パラメータとして文字を入力し、それを逆順に出したいです。
調べたりはしてみましたが、strlenを使用しないで文字列の長さを数えるやり方がわかりません。
カウントすると実行結果の表示文字数にばらつきが出てしまって。。。

コード:

#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[])
{
int i, j;

if (argc < 2) {
printf("error.\n");
return (-1);
}

for (i = argc - 1; i > 0; i--) {
/* argv[i]の長さ取得 */
int len = strlen(argv[i]);
for (j = len - 1; j >= 0; j--) {
printf("%c", argv[i][j]);
}
printf(" ");
}
printf("\n");

return (0);
}
表示の部分も多次元配列を使用せずに出来るのが可能であれば教えて頂きたいです。
よろしくお願いします。

Referia
記事: 24
登録日時: 9年前
住所: 奈良

Re: C言語 コマンド・パラメータ

#2

投稿記事 by Referia » 9年前

一次元の場合は
int length = sizeof(argv) / sizeof(argv[0]);
で、2次元の場合は
int FLength = sizeof(argv) / sizeof(argv[0]);
int SLength = sizeof(argv[0]) / sizeof(argv[0][0]);
で配列の長さを取得できます

恐らくこれでできると思います(未検証)

アバター
usao
記事: 1889
登録日時: 11年前

Re: C言語 コマンド・パラメータ

#3

投稿記事 by usao » 9年前

>文字列の長さを数える

C言語の文字列は(通常用途では?)末尾がわかるように終端文字 '\0' を最後に置く
(この文,正確な言い回しができる方,フォロー願います)
…ので,文字列の先頭側から見て行って,終端文字 '\0' を探せば良いのではないでしょうか.

コード:

//文字列を逆向きに出力する
void ReversePrint( const char *str )
{
    //終端文字を探す
    const char *p = str;
    while( *p != '\0' ){    p++;    }

    //文字列の長さ = (int)( p - str );

    //逆向きに一文字ずつprintfで出力
    while( p != str )
    {
        p--;
        printf( "%c", *p );
    }
}

//
int main(int argc, char* argv[])
{
    for( int i=argc-1; i>=1; i-- )
    {
        ReversePrint( argv[i] );
        printf( " " );
    }

    return 0;
}


>恐らくこれでできると思います(未検証)

mainの引数 argv に対して,その方法はダメなんじゃないでしょうか.
sizeof( argv )は sizeof( char** ) と同じ値を返すと思います.

Aozora0630
記事: 85
登録日時: 9年前
住所: 日本
連絡を取る:

Re: C言語 コマンド・パラメータ

#4

投稿記事 by Aozora0630 » 9年前

文字列を反対にするサンプル。

コード:

//最大文字数1000文字
char *ReverseString(char *str){
    char rstr[1000];//返り値
    int length = 0;//文字数
    int i = 0;//ループカウンタ
    
    for(length=0;;length++)if(str[length]==0)break;//文字列の長さを取得
    
    for(i=0;i<length;i++){
        rstr[i] = str[length-1];//反対にコピー
    }
    
    return rstr;
}
C系に於ける文字列やポインタはノリとかで覚えるのはやめた方が良いです。
(私ノリで覚えたw)
例え、ノリで覚えても必ず一度くらいはポインタや文字列の解説などを見たほうが良いです。

因みに、文字列は
・文字列は文字型(char)の配列で出来ている。
・文字列の最後には0が来る。(NULL文字
てな感じです。

また、文字列の最後にNULL文字、0が無いとどうなるかというと、

コード:

char st[1] = {'A'};
printf("%s",st);
上のコードを実行してみてください。(main無し
恐らくAの後に意味不明な文字列の羅列が出たと思います。
ポインタを知らないうちは何故0がいるのか知る必要はありませんが、ポインタを知ったら同時に知ることが出来ると思います。

>表示の部分も多次元配列を使用せずに出来るのが可能であれば教えて頂きたいです。
よろしくお願いします。
どういうことでしょうか。
引数を保存する時点で多次元配列が使用されていますのでWINAPIとかを使わない限り其れは無理だと思います。
オフトピック
私が初めてポインタの事を知った時、何故こんな便利なものがVBや其の他の言語に無いんだー
と驚愕しましたw
是非、これからも勉強してください。

追記:
NO.0のコードですが、多分13行目の
for (i = argc - 1; i > 0; i--)

for (i = argc - 1; i >= 0; i--)
にしないといけないと思います。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: C言語 コマンド・パラメータ

#5

投稿記事 by みけCAT » 9年前

Aozora0630 さんが書きました:文字列を反対にするサンプル。

コード:

//最大文字数1000文字
char *ReverseString(char *str){
    char rstr[1000];//返り値
    int length = 0;//文字数
    int i = 0;//ループカウンタ
    
    for(length=0;;length++)if(str[length]==0)break;//文字列の長さを取得
    
    for(i=0;i<length;i++){
        rstr[i] = str[length-1];//反対にコピー
    }
    
    return rstr;
}
rstrは静的でないローカル変数なのでこの関数から抜けると同時に消滅し、無効な領域へのポインタが返されることになります。

文字列を反対にするサンプル。(対象を直接書き換える)

コード:

void ReverseString(char *str){
    size_t length = 0;/*文字数*/
    size_t i = 0;/*ループカウンタ*/

    for(length=0;;length++)if(str[length]=='\0')break;/*文字列の長さを取得*/

    for(i=0;i<length-1-i;i++){
        char tmp = str[i];
        str[i] = str[length-1-i];
        str[length-1-i] = tmp;
    }
}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: C言語 コマンド・パラメータ

#6

投稿記事 by みけCAT » 9年前

かずま さんが書きました:表示の部分も多次元配列を使用せずに出来るのが可能であれば教えて頂きたいです。
よろしくお願いします。
配列をポインタで書き換えればできます。

コード:

#include <stdio.h>
#include <string.h>

int main(int argc, char **argv)
{
	int i, j;

	if (argc < 2) {
		printf("error.\n");
		return (-1);
	}

	for (i = argc - 1; i > 0; i--) {
		/* argv[i]の長さ取得 */
		int len = strlen(argv[i]);
		for (j = len - 1; j >= 0; j--) {
			printf("%c", *(*(argv + i) + j));
		}
		printf(" ");
	}
	printf("\n");

	return (0);
}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

かずま

Re: C言語 コマンド・パラメータ

#7

投稿記事 by かずま » 9年前

質問者とは別人の邪悪なプログラマのかずまです。

コード:

void rev_str(const char *s) { *s && (rev_str(s+1), putchar(*s)); }

void rev_arg(char **v) { *v && (rev_arg(v+1), rev_str(*v), putchar(' ')); }

int main(int c, char **v) {
    return (c = c<2) ? rev_str(".rorre") : rev_arg(v+1), puts(""), c;
}

Aozora0630
記事: 85
登録日時: 9年前
住所: 日本
連絡を取る:

Re: C言語 コマンド・パラメータ

#8

投稿記事 by Aozora0630 » 9年前

>質問者とは別人の邪悪なプログラマのかずまです。
ど、どうした。
二重人格?
記憶は共有しないの?

閉鎖

“C言語何でも質問掲示板” へ戻る