• ベストアンサー

0を含んだ文字列の長さ(バイト数)の求め方

環境:VC2005 WinAPI32 C言語 SDK 上記の環境でプログラミングをしています。 よろしくお願いいたします。 char str[256]=""; strcat(str, "ABC"); str[4]=0; strcat(str, "DEF"); たとえば上記のようなプログラムで、 str中のバイト数(文字列長?)を求めたいと思っています。 strの中身は [A][B][C][0][D][E][F][0][0][0]...[0]となっていますが、 このとき、7という値を取得したいのですが、何か効率的な方法はありますでしょうか・・。

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

  • ベストアンサー
  • a-saitoh
  • ベストアンサー率30% (524/1722)
回答No.3

今回求めたい文字情報より後ろの配列の内容がゼロクリヤされているという前提なら, '\0'でない,最後に現れる要素の位置を返せばいいでしょう. その前提が成り立たないなら,求めることは不可能です. int i, len; for(i=len=0; i<sizeof(str); i++)   if(str[i]) len=i+1; とか, int i, len; for(i=sizeof(str)-1, len=0; i>=0 &&str[i]=='\0'; i--)   ; len=i+1; どっちも効率的とは言い難いですが.

tanishi0718
質問者

お礼

回答ありがとうございます。 ご提示されたプログラムで7という値を求めることができました。 もうすこし、C言語を勉強したいと思います・・・。 どうもありがとうございました。

その他の回答 (2)

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.2

> strの中身は [A][B][C][0][D][E][F][0][0][0]...[0]となっていますが、 そうはならないと思います。 > strcat(str, "ABC"); で、[A][B][C][0]...[0] > str[4]=0; で、[A][B][C][0][0]...[0] (実際には変化無し) そして、 > strcat(str, "DEF"); で、[A][B][C][D][E][F][0]...[0] となるはずです。

tanishi0718
質問者

お礼

まさしくそのとおりでした。 すみません。例のプログラムをまちがえていました。 char str[64]=""; str[0]='A'; str[1]='B'; str[2]='C'; str[3]=0; str[4]='D'; str[5]='E'; str[6]='F'; とした場合に、7という値を求めたかったのです。すみません。

  • osamuy
  • ベストアンサー率42% (1231/2878)
回答No.1

> strの中身は [A][B][C][0][D][E][F][0][0][0]...[0]となっていますが [A][B][C][D][E][F][0][0][0]...[0] では。 \0で終端されるのがC文字列の定義なので、長さ情報を別途持つ必要があるかと。

tanishi0718
質問者

お礼

回答ありがとうございます。 すみません。例プログラムが間違っておりました・・。 char str[64]=""; str[0]='A'; str[1]='B'; str[2]='C'; str[3]=0; str[4]='D'; str[5]='E'; str[6]='F'; とした場合に、strから7という値を求めたいということでした。

関連するQ&A

  • mainから渡した文字列を関数内で書き換え

    非常に基礎的な質問で申し訳ないのですが mainから渡した文字列を関数内で書き換えることができません。 int型の整数やchar型一文字はできるのですが。。。 例えば以下のようなソースでmainのABCをDEFに書き換えたいとき どのようにすればいいのでしょうか。 (関数の戻り値で変更という方法以外で) 以下のソースでは値は書き換わりませんでした。 void func(char *str2) { str2 = "DEF"; } int main() { char str1[20] = "ABC" printf("%s", str1); //ABC func(str1); printf("%s", str1); //DEFになるようにしたい }

  • 文字列の連結するプログラム

    独学でプログラミングをやっているんですが2つ文字列を1つにする方法がよくわかりません。(1)のプログラムは(b+3)のところは文字の長さを指定しているからだめで(2)はstrcpyやstrcatなどのコマンドを使わずにやるそうです。While分とかでやるんでしょうか?教えてください。 (1) #include <stdio.h> int main (void){ char spelA[] = "abc"; char spelB[] = "def"; char spelC[20]; int a,b; spel[6]=0; for(a=0;spel[a]!=0;a++){ spelC[i] = spelA[i]; }; for(b=0;spelB[b]!=0;b++){ spelC[b+3] = spelB[b]; }; printf("%s\n",spelC); return(0); }; (2) #include <stdio.h> #include <string.h> int main (void){ char spelA[] = "abc"; char spelB[] = "def"; char spelC[20]; strcpy(spelC,spelA); strcat(spelC,spelB); printf("%s\n",spelC); return(0); }

  • 文字列に関する関数

    現在C言語の勉強をしております。 そこで、以下の関数の作成について質問させてください。 【関数の仕様】 引数の文字列から、'-'(ハイフン)と'P'以降を排除した文字列を返す。 自分なりに作成してみたのですが、コンパイルで警告が出てしまう状況です・・・。 もっとスマートに書けるんだろうとは思っているんですが、精一杯でした・・・。 どなたか教えていただけませんでしょうか? char *getDelStr(char *str) { int len = strlen(str); int count; char targetStr[32]; for(count = 0; count < len; count++){ if(str[count] != 'P'){ if(str[count] != '-'){ strcat(targetStr,str[count]); } }else{ return targetStr; } } return str; } 以上、よろしくお願いいたします。

  • Cでは文字列をどのように認識するのでしょうか?

    C言語には文字列型というものは存在しないと教わりました。 文字列の終わりはヌル文字で認識できますが、 文字列型というものが存在しないのに何故次のバイトを読もうとするのですか? たとえばchar str[] = "abc";、あるいはchar *p = "abc";とあったとして printf(str);あるいはprintf(p); でなぜabcが出力されるのでしょうか?なぜaの次にbがbの次にcがあるとわかるのでしょうか? char型で先頭アドレスが渡された場合、ヌル文字を見つけるまでアドレスをインクリメントし続けるという決まりでもあるのでしょうか? それに文字列型というものが存在しないなら''と""を分ける意味もないのでは??

  • TCHAR文字列内の検索について

    TCHAR文字列内の検索について 質問があります。 #include <tchar.h> TCHAR tex1[8]; TCHAR tex2[8]; TCHAR tex3[8]; TCHAR buf[128] = TEXT("abc,def,ghi"); TCHAR型で宣言された変数bufには、「abc,def,ghi」が格納されているとして、 結果的に tex1 → "abc" tex2 → "def" tex3 → "ghi" となるようなプログラムを作ろうと考えています。(buf内をコンマで区切って3つの変数に代入) まずコンマの位置が何文字目にあるか確認するために TCHAR ret[128]; TCHAR search[128] = TEXT(","); ret = _tcschr( buf, search); としてみましたが、やはりうまくいかずにエラーが出ます。 上記の目的を達成するにはどのようなプログラムを作ればよいのでしょうか? 環境はVisual C++ 2008 Expressで、C言語を使ってプログラミングしています。

  • C++でSTLを使った文字列操作

    C++素人です。 第一引数で指定するファイルパスの 拡張子を.datに変更する関数を作っていますがうまくいきません。 STLの使い方が悪いのでしょうか? #include <string.h> using namespace std; char *exchange(const char *fname) { char *file; char *ex; string str; str = fname; ex = ".dat"; str.erase(str.find_last_of('.')+1); file = strcat(str, ex); return file; } int main(int argc, char *argv[]) { char *file = exchange(argv[1]); return 0; }

  • abcが、入力された文字列内にあるかどうかを表示するプログラム

    文字列strの中にabcが含まれていれば、1を返し、含まれていなければ0を返すプログラムが分かりません。 C言語の問題で下記のものが分かりません。どなたか知恵を貸してください。 ユーザが文字を入力し、CTRL+Zが押されるまで、半角英数字の入力(最大でも1000文字)を受け付ける。文字列「abc」が、入力された文字列内にあるかどうかを表示するプログラムを作成する。ユーザが入力した文字列が3文字未満はabcがありませんと表示させる。 そのプログラム内で以下の関数を完成させる。 int str_srch_abc(char str []) 文字列strの中にabcが含まれていれば、1を返し、含まれていなければ0を返す関数とする。 (例えばabcは連続でabcの時だけ1を返し、asbscなどはoを返します。) ちなみに自分なりにやってみたのですが、ここまでしかできませんでした。 #include<stdio.h> int main() { int str_srch_abc(char str []); char str[1000]; int ch=0, j=0; printf("半角英数字を入力してください"); scanf("%s",str); while((ch=getchar())!=EOF){ str[j]=ch; j++; } str[j]='\0'; printf("%s",str); return(0); }

  • マルチバイト混在の文字列整形

    OS: Linux Ubuntu 言語: C++ 引数でchar*型の文字列配列(マルチバイト含む)を受け取り 指定した幅で枠つきで文字列を出力したいのですがうまくいきません。 作りたい出力 ━━━━━━━ ┃1: あいうえお┃ ┃2: かきく   ┃ ┃3: abc    ┃ ━━━━━━━ - str[] = {"あいうえお", "かきく", "abc"} - あいうえおの後ろは空白なし - 他は空白と文字列を合計してあいうえおと同じ長さに合うように 私の環境では日本語は3byteと認識され  strlen("あいうえお") = 15 となります。 イメージでは for (i = 0; i < strlen(str[])の最大値; i++) { cout << "┃" << i << ":" << setw(15) << left << str[i] << "┃" } のようなコードになると思うのですが 日本語一文字が出力上は2byte分の幅に見えるのに 認識としては3byteになってしまうので空白が1byte多くなり ━━━━━━━ ┃1: あいうえお┃ ┃2: かきく    ┃ ┃3: abc       ┃ ━━━━━━━ のようにずれてしまいます。 (表記上、最初の枠もずれていますが  現状は足りない分を埋めるsetfillが余計に働いてしまうということです。) 何か対策はありますでしょうか?

  • 文字列内の数字削除

    C言語の質問です。文字列str中の数字文字を削除する関数をポインタを使って作りたいのですが、どう作ったらいいかわかりません。方向性だけでも教えてくれませんか。 ちなみにヒントとして以下の部分は与えられてました。よろしくお願いします。 void del_digit(char *str) { char *ptr = str; while(*str){

  • 文字列の扱いについて教えてください

    #include<cstdio> #include<cstring> #define _CRT_SECURE_NO_DEPRECATE 1 #define MAXBUFF 256 void s_swap(char* str_a, char* str_b) { char str_dummy[MAXBUFF]; strcpy_s(str_dummy,strlen(str_dummy),str_a); ★ strcpy_s(str_a,strlen(str_a),str_b); ★ strcpy_s(str_b,strlen(str_b),str_dummy); } void main(void) { char* str_a = "ABC"; char* str_b = "DEF"; int a; printf("呼出前:str_a=%s, str_b=%s\n", str_a, str_b); s_swap(str_a,str_b); printf("呼出後:str_a=%s, str_b=%s\n", str_a, str_b); } str_aとstr_bの中身を入れ替える処理で、エラーや警告はでないのですが ★のところで実行失敗します。 昔から文字列の処理は苦手でどのように攻略したらよいのか 解説していただけないでしょうか。

専門家に質問してみよう