strtokの問題というよりも、文字列とポインターの考え方がまだちゃんと分かってないせいだとは思うんですが、strtok()のところで、Access Violationとでます。すごく単純そうな問題だとは思いますが、教えてください。お願いします。

#include <iostream.h>
#include <string.h>

int main() {

char *chk = "3453/5252";
char *tokenPtr;

tokenPtr = strtok(chk, "/");

while (tokenPtr != NULL) {

tokenPtr = strtok(NULL, "/");
}
return 0;
}

このQ&Aに関連する最新のQ&A

A 回答 (5件)

> 静的なバッファ…


 "変数領域" に確保する配列のことです。例えば、関数の外で定義した配列は "静的" になります。(関数内で定義することもできますが…詳細は割愛します)

> ポインターとはconst array …
 この場合の "3453/5252" は "定数領域" にありますので const になります。ですので char *chk = "3453/5252" とすると chk に代入されるのは const ポインタです。
 関数内で char chk[] = "3453/5252" とすると、文字列はスタック上の領域(auto 変数)にコピーされ、chk にはその領域を指すポインタが代入されます。これは const ではありません。

> chkにはユーザーが入れた値を代入したいので…
 いずれにしても入力された文字列を蓄えておく領域(文字配列・バッファ)は必要でしょうし、予想される文字数が十分入るサイズを確保した上で、文字数超過でバッファがあふれないようにする対策も避けて通れないと思います。
    • good
    • 0
この回答へのお礼

route156さん、deagleさん、分かりやすい説明をしてくださって、ありがとうございました。ポインターと配列に関する疑問が、もうそろそろ解けそうな気がしてきました。本当にありがとうございました。

お礼日時:2002/03/18 23:11

 これは変数 chk を定義するときに一緒に文字列を代入してしまっているのが原因です。


 これは route156 さんがおっしゃっているのと同じことです。
 しかし、

  char chk[] = "123";
  char *chk = "123";

 この2つは同じ意味なので、実際にはこうしなければいけません。

  char chk[10];
 strcpy( chk, "123/456" );

 これならば、chk の中身が改変可能になるのでエラーは出ません。

 で、上記の例では [10] というふうに文字列の長さを固定してしまっていますが、このような宣言の変数を「静的変数」といいます。
 逆に、

  char *chk;
  chk = (char*)malloc(10);

 というように、文字列の長さをプログラム内で可変的に作成した変数を「動的変数」といいます。

 なお、C言語では、「文字列の長さを決めずに処理をする」のは不可能です。もしそれをやりたければC++の CString などを使わなければいけません。
 これは、C言語がもともと、「システムを直接操作する」ことを目的とした言語だからです。
    • good
    • 0

 strtok() は与えられた文字列内の区切り文字の部分に '\0' を書き込みますので、Access Violation は定数として文字列を与えているのが原因だと思います。


 文字列を収める場所を別に確保してみてはどうでしょう。

int main(void)
{
 char chk[] = "3453/5252";
 …以下略

※ malloc() を使っても、静的なバッファに strcpy() しても良いと思います。

この回答への補足

実は、chkにはユーザーが入れた値を代入したいので、配列を使うとなると、要素の大きさを決めなければいけなくなりどこかでエラーになるような気がするのです。後もう二つ質問させてください。

静的なバッファとはなんでしょう?

どこかで聞いたことがあるのですが、ポインターとはconst arrayなのでしょうか?

補足日時:2002/03/14 12:37
    • good
    • 0

ごめんなさい。

No.1は無視して下さい。
勘違いしました。
で、あれ?おかしいところは見当たりませんけれど。
ひょっとして、strtok()の入っているダイナミックライブラリの
アクセス権がないとか...。

この回答への補足

ダイナミックライブラリとはDLLのことですか?ネットワークに繋がれてない、WIN98で動かしているので、アクセス件の問題ではないと思うのですが。。。

補足日時:2002/03/14 12:01
    • good
    • 0

strtok(NULL, "/")


は何を意図しているのでしょう。
明らかに第1引数のNULLが問題ですが。
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qchar c = 'a'; char h[1] = c; エラー

char型のものを char[]型に代入したいです。

char c = 'a';
char h[1] = c;

として、

h[0] は \x97
h[1] は \x00

にしたいです。
型変換の方法を教えてください。

Aベストアンサー

とりあえず、確認を。

C では、'a'の表す値は 0x61 = 97 であって、 \x97 ではないと思います。
(\xnnn を、十六進数の意味に取りましたが、あってますでしょうか?
この場合、C では通常 0xnnn のように書くと思います。)
ので、 これは 0x61 のことをおっしゃっていると仮定します。

> char h[1] = c;
っと、これではたぶんコンパイルが通りません。

char h[1] = {c};

のように、配列であることを明示して代入してください。
この式では、前半でh という名前の、*長さ1 の* char の配列変数を確保します。
後半で、その中を初期化しています。
添え字は 0 からはじまるので、この場合、h[0] に c の内容が代入されます。
1個しか場所を確保していないので、 h[1] の位置のデータは内容が不定です。
文字列として h を扱いたいのであれば、 C の文字列には終端として 0 が必要ですから、
char c = 'a';
char h[2] = { c, '\0'};

のような書き方が必要になります。
これで、お望みのデータになると思います。

とりあえず、確認を。

C では、'a'の表す値は 0x61 = 97 であって、 \x97 ではないと思います。
(\xnnn を、十六進数の意味に取りましたが、あってますでしょうか?
この場合、C では通常 0xnnn のように書くと思います。)
ので、 これは 0x61 のことをおっしゃっていると仮定します。

> char h[1] = c;
っと、これではたぶんコンパイルが通りません。

char h[1] = {c};

のように、配列であることを明示して代入してください。
この式では、前半でh という名前の、*長さ1 の* char の配列変数...続きを読む

Q{x = x>y ? x:y; return x;}

#include <iostream>
using namespace std;

inline int max(int x, int y){x = x>y ? x:y; return x;}

int main()
{
int num1, num2, ans;

cout << "2つの整数を入力して。\n";
cin >> num1 >> num2;

ans = max(num1, num2);

cout << "最大値は" << ans << "です。\n";

return 0;
}
の{x = x>y ? x:y; return x;}の部分の意味が解りません。

Aベストアンサー

inline int max(int x, int y){x = x>y ? x:y; return x;}
これを普通に関数で書くと

int max(int x, int y)
{
x = x>y ? x:y;
return x;
}

です。

x = 部分は右辺の結果が代入されます。これはわかりますよね。
x>y?x:y;
と書くと?より左にある条件式を判定し、その結果が真である場合は:で区切られた左側の値を、偽である場合は右の値を帰します。
x>yが真であればxを、偽であればyを返します。
それが、左辺値xに代入され、関数の戻り値として帰ります。

従って、2つの値をこの関数に入れると、大きいほうの値が帰ることになります。

Qchar AA[]{"全角文字"};から"全"という一字を取り出したい

 今晩は、Cの初心者です、宜しくお願いします。
 全角文字の入ったchar AA[]{"全角文字"};から"全"という文字一字を取り出す時にAA[0]とかくとエラーになります。
 どのようにしたら取り出せるのでしょう。
 ポインタを使う方法と使わない方法を教えて下さい。
 宜しくお願いします。

Aベストアンサー

お疲れ様です。

まずお伺いしたのがOSおよび開発するためのコンパイラです。

ロケール等の話は分かりませんが、昔のC言語で日本語を扱う場合には全角文字1文字で2個つのchar領域を使用していました。
(マルチバイト文字セットと言います。)

詳細は参考URLを参照の事。

windowsでVCと仮定した場合、charを使われていると言うことは、多分、shift-jis(シフトJIS)で文字列を扱っていると思われます。

結論として全角文字1文字だけを取り出したいという場合は、結局char2個分のデータを取り出す必要があります。

>char AA[]={'全','角'};

char AA[]="全角";
とし
>printf("%s%s\n" , AA[0],AA[1] ) ;

printf("%c%c\n" , AA[0],AA[1] ) ;
とすれば、「全」だけを表示する事が可能と思われます。

日本語を文字列で表示する為の文字コードについては
Shift-JISだけでなく、UnicodeやUTF・EUC・JISなどがあります。

もう少し詳しく記載してあるホームページはないか探してみましたが、ちょっと無理でした。

参考URL:http://marupeke296.com/CPP_charUnicodeWideChar.html

お疲れ様です。

まずお伺いしたのがOSおよび開発するためのコンパイラです。

ロケール等の話は分かりませんが、昔のC言語で日本語を扱う場合には全角文字1文字で2個つのchar領域を使用していました。
(マルチバイト文字セットと言います。)

詳細は参考URLを参照の事。

windowsでVCと仮定した場合、charを使われていると言うことは、多分、shift-jis(シフトJIS)で文字列を扱っていると思われます。

結論として全角文字1文字だけを取り出したいという場合は、結局char2個分のデータを取り出...続きを読む

Qtry{}catch(){}とデストラクタの関係を教えてください。

try-catchでメモリ確保を含むクラスをスローした場合、デストラクタはどの時点で働くのか、教えてください。たとえば、↓の使いかたは大丈夫でしょうか?

【1】
try{
 throw(CError(100, "エラー情報"));
}catch(CError& err){
 //ここでerrを参照しても問題ないのでしょうか?
}

【2】
try{
 CError err(100, "エラー情報");
 throw(err); // (1)
}catch(CError& err){
 //ここでerrを参照しても問題ないのでしょうか?
 //まだデストラクタはちゃんと動作するのでしょうか?
 //catchが呼び出し元のメンバであったりしても大丈夫なのでしょうか?
}

宜しくお願いします。

Aベストアンサー

【1】【2】どちらの場合も問題がありません。
コンパイラが必要に応じてerrオブジェクトのコピーを作成します。
デストラクタが呼び出されるタイミングはコンパイラに依存するところもあると思いますが、
例えばVC7.1では【2】は以下のように動作します。
(1) errオブジェクトのコンストラクタが呼び出される
(2) CErrorクラスのテンポラリオブジェクト(以下a)のコピーコンストラクタが呼び出される。
(3) errオブジェクトのデストラクタが呼び出される
(4) catch文まで到達
(5) aオブジェクトのデストラクタが呼び出される。

VC7.1では、【1】は以下のように動作します。
(1) errオブジェクトのコンストラクタが呼び出される
(2) catch文まで到達
(3) errオブジェクトのデストラクタが呼び出される。

コンパイラがオブジェクトのコピーを省略しているようです。

Qchar *str; と char* str;

char *str; と char* str;
どっちも同じことを意味しているんですか?

Aベストアンサー

同じことを指している、というのは、先の回答の通りです。

また、ひとつの宣言で変数を複数宣言したときに、char* str という表記は間違い
易いじゃないか、ということが言われているのも事実です。実際、いろいろな C のソースを
見ていても、まずアスタリスクを型につけて書くのは、まずお目にかかれません。

ただ C++ では、char* str という宣言も良く使われています。

C++ に限らずオブジェクト指向の言語は、強く型を意識するので、「文字のポインタ型」と
いう意味で、まとめて書く方が馴染むのでしょう。ちなみにそういう風な人たちは

char *str1, *str2;

とは、書けない体になっています。

char* str1;
char* str2;


変数の宣言だと、C に慣れていれば、char* str というのはちょっと違和感があるのは
私も分かりますが、関数のプロトタイプ宣言だと、どちらの方がすっきりしますか?

extern char *memcpy(char *, const char *);

extern char* memcpy(char*, const char*);


# まあ、どっちが正しい、っていうんじゃ無いんですよね

同じことを指している、というのは、先の回答の通りです。

また、ひとつの宣言で変数を複数宣言したときに、char* str という表記は間違い
易いじゃないか、ということが言われているのも事実です。実際、いろいろな C のソースを
見ていても、まずアスタリスクを型につけて書くのは、まずお目にかかれません。

ただ C++ では、char* str という宣言も良く使われています。

C++ に限らずオブジェクト指向の言語は、強く型を意識するので、「文字のポインタ型」と
いう意味で、まとめて書く方が馴染む...続きを読む


人気Q&Aランキング

おすすめ情報