テキストファイルで、
   1,2,3,4,5,
   6,7,8,9,10,
   11,12,13,14,15,
のような数字の並びがあったとします。
それを読み込んで
 a[0]={1,2,3,4,5}
a[1]={6,7,8,9,10}
a[2]={11,12,13,14,15}
のように、次のカンマまでの値を2次元配列にいれる、ということをやりたいと思っています。
fgets あたりと、strpbrk( ×××,"," )をうまく使えばいいと思い、いろいろやっているのですが、うまくできません。
また、ファイルの最後までを配列に入れたら終了、というのも、どう記述していいかわかりません。
どうぞよろしくお願いします。

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

A 回答 (2件)

> data.txtの中身に英語が混じっていた場合



strtok() で切り出した文字列が *数字とみなせない場合* を判別するには、
strtol() の第二引数を利用します。

char* buf[1024];
char* p;
long data;
data = strtol(buf, &p, 0);

とすると、もし buf が数値とみなせなければ、p は buf の最初を指します。
もし buf の先頭からいくつかが数字とみなすことができれば、数値と
みなせなくなった場所を指します。

提示されたような丸々数値とみなせない場合には、

char* ep;
data[i][j] = (int)strtol(v, &ep, 0);
if (*ep == '\0') { /* 文字列の最後を指している、ということは数値だったということ */
  ++j;
}

というようにすれば、数値の場合だけ j がカウントアップされてゆきます。
    • good
    • 0

strpbrk() を使うと、カンマの場所を見つけるだけで、次のカンマまでを


ひとくぎりで見る処理をしなければならないので、ちょっと面倒です。

こういうことをするために strtok() という関数が用意されています。
ちょっと書いてみましたが、こんな感じ。

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

int main()
{
  char* tok = ", \t\n"; /* 念のため、カンマ以外に空白・タブ・改行文字も数値の区切りとして扱う */
  char buf[1024];
  FILE* f = fopen("data.txt", "r");
  int data[10][10];
  int i = 0, j;
  memset(data, -1, sizeof(data));
  while (fgets(buf, sizeof(buf), f) != NULL) /* これが、「ファイルの最後まで」にあたる */
  {
    char* v;
    /* このループが、一行の内容をカンマでばらして行く処理 */
    for (j = 0, v = strtok(buf, tok) ; v != NULL ; ++j, v = strtok(NULL, tok))
    {
      data[i][j] = (int)strtol(v, NULL, 0);
    }
    ++i;
  }

  return 0;
}

この回答への補足

小数の場合、できました!!strtodなんてのがあったんですね。
知らなかった。勉強になりました。
英語が混じった場合の方、アドバイスよろしくお願いします。

補足日時:2001/08/24 19:16
    • good
    • 0
この回答へのお礼

ありがとうございます!!
できました!!ずっと詰まって悩んでいたところが解決しました!!大感謝です!!

ところで、もしdata.txtの中身が小数の場合
int data[10][10]→double data[10][10]
(int)strtol(v, NULL, 0); →(double)strtol(v, NULL, 0);
にすればいいと思ってやってみたのですが、うまくいきません。
他にどこを変更すればいいのでしょうか。
またdata.txtの中身に英語が混じっていた場合,例えば
A 1,2,3,4,5,
B 6,7,8,9,10,
のような場合,英語を無視して数字のみを配列に入れる、ということはできるでしょうか。
  

お礼日時:2001/08/24 18:55

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

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

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

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

Q読点とカンマの違い

「読点」の意味を辞書で引いたら下のようにでていたのですが、今ひとつよく意味が解りません。英語のカンマとはどう違うのか説明してほしいんですが。


味の切れ目を示すため、文中に施す「、」の符号。→句点

お願いします。

Aベストアンサー

「味の切れ目」→「意味の切れ目」ですね。(^^)

で,既に出ている回答とも重なりますが,日本語でも横書きの場合はカンマを使うことがあります。特に数字やアルファベットのあとに読点が来ると何となく間が抜けてみえるので,数字や欧文を多用する理工系の図書や雑誌などに多く見られます。
この文章もそのスタイルで書いています。なので,farsideさんの前の質問(http://oshiete1.goo.ne.jp/kotaeru.php3?q=98303)の回答で「今も使っていません。」と断言されてしまうと,私が書いているのは一体何なの?と,ちょっと困ってしまいます。
あ,よく見ると「正式な日本語の文章にカンマはありません。」でしたね。正式じゃないからいいのか。でも,それなら正式な日本語って何? 理工系の図書や雑誌は大多数が正式じゃないってこと? 「公用文の書き方」(という政府の内部規定)が正式? じゃ民間の文章はみんな正式じゃないのか? よくわからなくなってきました。

話を戻しますと,横書きの日本語でカンマを使うか読点を使うかは,単にその図書なり雑誌なりの出版社が編集方針として決めているだけのことで,機能的には従来からの読点と何ら変わりがありません(数値の区切りとかは別)。
では,その日本語本来の読点と,英文のカンマはどう違うかというと…基本的には,文(センテンス)の中に打って,意味上の切れ目を示すわけですから,似たようなものといってよいでしょう。
ただ,細かく見ていくと,そもそも英文法と日本語文法が違いますので,比較のしようがなくなってくると思います。たとえば,英語では関係節と主節を区切る時に使いますが,日本語ではそもそも関係代名詞がありませんね。

英語のカンマの打ち方は,文章のルールブックというのがいろいろとあって,それを見ると出ています。代表的なものとして,Chicago Manualの中から該当のページを参考URLに載せておきました。カンマの打ち方だけで,全部で27項目あります。

ちなみに,中国語では読点(、)は並列を表し(日本の中黒「・」のような使い方),それ以外はすべてカンマです。横書きでも縦書きでも一緒です。
日本語で書くとこんなふうになるでしょうか。「私は,彼女と一緒に,京都、奈良、大阪、神戸を旅して回った。」

参考URL:http://www.publicbookshelf.com/public_html/Manual_of_Style/commarule_i.html

「味の切れ目」→「意味の切れ目」ですね。(^^)

で,既に出ている回答とも重なりますが,日本語でも横書きの場合はカンマを使うことがあります。特に数字やアルファベットのあとに読点が来ると何となく間が抜けてみえるので,数字や欧文を多用する理工系の図書や雑誌などに多く見られます。
この文章もそのスタイルで書いています。なので,farsideさんの前の質問(http://oshiete1.goo.ne.jp/kotaeru.php3?q=98303)の回答で「今も使っていません。」と断言されてしまうと,私が書いているのは一体何なの?と...続きを読む

Qint nII[10] = { 0 }について

久々にCを使ってプログラムを組んでいるのですが、基本的な構文を思い出せず
いくつか教えていただきたく質問させていただきました。

1)配列すべてを初期化するのに、宣言時に

int nII[10] = { 0 };

で大丈夫だった(全ての要素が0で初期化)と記憶しているのですが、間違いないでしょうか?

2)構造体の初期化は

struct tm tm;
memset(&tm, 0, sizeof(struct tm))

で大丈夫でしょうか?

3)構造体の宣言は

typedef struct{
int a;
}HOGE, *LPHOGE;

HOGE st; // <- struct HOGE stと同じ
LPHOGE pst; // <- struct HOGE* pstと同じ

で問題ないでしょうか?

以上、3つ質問になって申し訳ないのですが、よろしくお願いします。

Aベストアンサー

1)OK
2)たぶんOK
3)HOGEという名前の構造体はない(当該の構造体には名前がない)ので、
// 以下のコメント記述が誤っています。ただし、

HOGE st;
LPHOGE pst;
という定義そのものはOK

Q電卓 パソコン カンマの位置の違い

999円以上の数字を打つときにパソコンと電卓とで不思議に思うことがあります。

例えば「1000」と表記する時に
千の位と百の位の間の下に「,(コンマ)」を入れて
「1,000」とするようですが
なぜ電卓では上にコンマを入れるのでしょうか?
(私が保有している電卓だけなのか?)

電卓では
区切り点と小数点を見やすくするためですか?
しかしもしそうなら
なぜ電卓だけで、普段のパソコンなどでの書式は
区切り点と小数点も下に点をつけるのでしょうか?

 何かわかる方よろしくお願いします。

Aベストアンサー

> なぜ電卓では上にコンマを入れるのでしょうか?

・日本(アメリカ、イギリス)では、3桁ごとの区切りは「,」カンマ、小数点は「.」ピリオドが使われています。
ところが、ヨーロッパ圏を主体に、日本とは逆の3桁ごとの区切りは「.」ピリオド、小数点は「,」カンマが広く使われています。

近年、インターネットオークションなどで、桁取りや少数点でトラブルが多発するようになりました。
そこで、2003年10月17日にフランスのパリで行われた国際度量衡(どりょうこう)総会(CGPM)で、小数点を統一するための会議が行われました。

この国際会議で決定されたのが、なんと、なんと、、、
・「小数点は、ピリオドまたはコンマのどちらでもOK」と決められました。
・その代わり「3桁ごとの位取りはスペースを用いる、または、無し」となりました。

例: 123 456 789.012(ピリオド) または 123 456 789,012(コンマ) と定められました。


第22回国際度量衡総会決議(PDF)
http://www.intermet.jp/metric/22ndCGPM.pdf
原文
http://www1.bipm.org/jsp/en/ViewCGPMResolution.jsp?CGPM=22&RES=10

=ご質問に係わる要約=(上記PDFの7ページ)
2003年、第22回国際度量衡総会において、小数点は「小数点は、ピリオドかコンマのどちらかとする」と決められました。
3桁区切りは、3桁ごとに空白を入れて読みやすくするのは構わない。
しかし、混乱を避けるため3桁区切りに「コンマやピリオド」を使ってはならないと規定されています。

そこで、2003年以降の電卓では、従来の位置に3桁区切り「コンマ」を使うことが出来なくなったため、電卓メーカーは、苦肉の策としてzxdaeg様のご質問の通り、上部に印(マーク)を付けています。

添付写真の通り、古い電卓では、従来の位置に3桁区切り記号があります。

> なぜ電卓では上にコンマを入れるのでしょうか?

・日本(アメリカ、イギリス)では、3桁ごとの区切りは「,」カンマ、小数点は「.」ピリオドが使われています。
ところが、ヨーロッパ圏を主体に、日本とは逆の3桁ごとの区切りは「.」ピリオド、小数点は「,」カンマが広く使われています。

近年、インターネットオークションなどで、桁取りや少数点でトラブルが多発するようになりました。
そこで、2003年10月17日にフランスのパリで行われた国際度量衡(どりょうこう)総会(CGPM)で...続きを読む

Qfp = fopen(argy[1], "r");の[1]の意味は

https://oshiete.goo.ne.jp/qa/8940272.html
 の11行目に
fp = fopen(argv[1], "r");の[1]の意味が分かりません。
試したいのですが、ソフトがうまく動きません
 よろしくお願いいたします。

Aベストアンサー

前の例題も読みました。

大分苦戦しているようですが、配列については理解が進みましたでしょうか?
お答えしますと、最初のパラメータ文字列が代入されています。

古いC言語の約束でして大変有名なものです。

コマンドラインコンソールから実行ファイル名を書いて、
パラメータをスペースで区切って指定したとします。

このパラメータ文字列が[1]以降に入ります。
例として、"test"と言う名前の実行ファイルがあったとします。

例)> test test1 test2 3 4

このようにコマンドラインから入力し実行すると、

argc = 5
argv[0] = "test"
argv[1] = "test1"
argv[2] = "test2"
argv[3] = "3"
argv[4] = "4"

と文字列が入ってきます。

以下はサンプル。

void main( int argc , char *argv[])
{
if( argc < 2 )
{
// パラメータ指定がなかった場合の表示
printf( "test に続けて4つまでパラメータを入力できます\n");
exit(0);
}
if( argc > 5 )
{
 // パラメータが5つ以上あった場合の表示
printf( "5つ以上のパラメータは受け付けません\n");
exit(-1);
}

// 正常ルート
printf( "パラメータの数は%d個ですね?ニヤッ\n", argc-1);
printf( "最初のパラメータは%sでしょ?\n", argv[1]);
printf( "残りはargv[2]以降ですが、面倒なので表示しません\n");
}

と言う具合に、引数を活用できます。argv[0]には、実行ファイル名が入ります。
argc は実行ファイルの名前も含めてカウントされます。

プログラムによっては必要な引数の数が変わりますし、
ユーザーのコマンドラインからの入力ミスなどでパラメータがなかったり、
必要なパラメータが不足していたりしますので、
argcとargvを使って最初にシンタックスエラーチェックをするのが常道です。

実行ファイル名の指定がなく、プログラムが実行されることはないと思われます
から、argcは1以上の値になります。

argc, argvの活用は、
実行コマンドを手打ちで打ち込むコンソール形式でよく用いられる基本的な
アプリケーションの開発手法です。

ご質問の箇所は、
第一パラメータにプログラム内で読み込むファイルのファイル名を指定してるの
でしょう。(よくあります)

しかし、Windowsなどのウィンドウを使用するアプリケーションは、
これとは違っておりますので注意が必要です。
(C言語とは別に、Windowsに特化した開発ノウハウの勉強が必要です)

Windows系で上記の様な基本的なプログラムを作成する場合は、
プロジェクトの作成時に(VisualStudioなどで)コンソールアプリケーション
を選んで作成します。実行時にコンソールが開きます。

Linuxの場合は、コンソールがデフォルトになっているでしょうから、
(特殊な設定がなければ)そのまま作成できます。

テキストエディタでソースを記述し、gcc などでコンパイルします。
実行形式ファイルが出来ていれば、想定どおりの動作をするでしょう。

ファイルの読み込みが出来るようになったら、
ファイルの内容を書き換えて保存したり、
ファイル名を変えたり、
ディレクトリ内のファイルを全て表示したり、
ファイル内に含まれる文字列を検索し、該当するファイルをリストしたりなど、

有用なサンプルプログラムを沢山作って練習します。

ファイルを読み込む先は、char型の配列でバイトサイズのメモリーとして確保
します。メモリーと変数の関係を充分に理解することをお勧めします。
殆どのプログラムは、このメモリーの確保やメモリーサイズの計算と格闘する
場合が多くなるからです。

バイナリー形式のファイル(すべてはバイナリー形式として良いのですが)に
ついて理解が深まった後は、
bmpの画像ファイル、wavなどの音声ファイルをあけて、
これの中身を書き換えて遊びます。

特にwavファイルは、音量の変更や周波数フィルタなども掛けれますので、
メモリ、配列、ファイルの関係を(焦らずに)ゆっくり理解するだけで、
今の知識レベルでも面白いことが沢山出来ます。

以上、ご参考に成れば。

前の例題も読みました。

大分苦戦しているようですが、配列については理解が進みましたでしょうか?
お答えしますと、最初のパラメータ文字列が代入されています。

古いC言語の約束でして大変有名なものです。

コマンドラインコンソールから実行ファイル名を書いて、
パラメータをスペースで区切って指定したとします。

このパラメータ文字列が[1]以降に入ります。
例として、"test"と言う名前の実行ファイルがあったとします。

例)> test test1 test2 3 4

このようにコマンドラインから...続きを読む

Q英文中のカンマの使い方について

英文の中で、so の前のカンマが有るのと無いのがありますが、なぜですか?違いは何ですか?

全般的に、カンマの打ち方、法則みたいのがあれば教えてください。

宜しくお願いします。

一応自分でも調べてみたのですが、難しい説明でしたので、・・・簡単に解説していただければ幸いです。

Aベストアンサー

「だから」のような意味の時はコンマを使うことがあります。しかし、法則という程のものはありません。so が very のような「とても」という意味になる時はコンマは使いません。very good, so good 、どちらもコンマは使いません。

Qa[i]とa[i+1]を入れ替えるような関数を作成するC言語の問題

以下のように配列aとそのサイズsとインデックスiを引数
にとり、a[i]とa[i+1]を入れ替えるような関数を作成する問題。

但し、この関数内で配列の外側をアクセスしないようにエラー
チェックをすること。正常に処理が終了した場合は0を返し、
そうでない場合は-1を返すようにする。

main関数では、10個分の整数を入れる配列を宣言し、
データをユーザに入力させる。
次に、ユーザに1個整数を入力させ、0からその番号まで順に
iをずらしてswap_array関数を読んだ後、配列に入っているデータを
表示させる。

・配列にデータを入力でき、交換が正しくできている
・ユーザが配列の外側を指定した場合は、エラーである旨を
表示して終了する。

取りあえずこうゆうかんじになるのですが、//の前などをどうにすればいいか分かりません。分かる方は知恵を貸してください。

int swap_array(int a[], int s, int i)
{
//a[i]番目とa[i+1]番目を入れ替え処理をする

//正しく交換できた場合はreturn(0);
//エラーが発生した場合はreturn(-1);
}
int main()
{
//サイズ10の配列の宣言
int a[10];
//ユーザに10個のデータの入力をさせる
int i;
for(i=0;i<10;i++){
scanf("%d",&a[i]);
}
//0番目から何番目まで入れ替えるかユーザに聞く: (ユーザがnと入力)
int n;
......

//繰り返し構造を使って、0番目からn番目まで隣同士を交換
for(i=0;i<=n;i++){
int v;
// swap_arrayを繰り返し呼び出すが、毎回戻り値が0であることを
        //チェックしてエラーが発生していないことを確かめる
v=swap_array(a,10,i);

// エラーが発生していたら エラーが発生したことを表示して
//break;文で繰り返し構造から外にでる。
if(v==-1) break;
}

//エラーが発生しなかった場合に、入れ替えられた配列の内容を表示
if(v!=-1){
..... 配列の内容を表示
}

return(0);

以下のように配列aとそのサイズsとインデックスiを引数
にとり、a[i]とa[i+1]を入れ替えるような関数を作成する問題。

但し、この関数内で配列の外側をアクセスしないようにエラー
チェックをすること。正常に処理が終了した場合は0を返し、
そうでない場合は-1を返すようにする。

main関数では、10個分の整数を入れる配列を宣言し、
データをユーザに入力させる。
次に、ユーザに1個整数を入力させ、0からその番号まで順に
iをずらしてswap_array関数を読んだ後、配列に入っているデータを
...続きを読む

Aベストアンサー

こんな感じではだめでしょうか…。

#include <stdio.h>

unsigned int swap_array(int a[],unsigned int size,unsigned int s)
{
unsigned int temp,i=s;
if (size<s) return s;// 要素数を返す
while (i-1) temp=a[s-i+1],a[s-i+1]=a[s-i],a[s-i--]=temp;
return 0;
}
int main()
{
int a[10];
unsigned int n,i=0,size=sizeof(a)/sizeof(unsigned int);

do{
printf("%d個目のデータ?",i+1);
scanf("%d",&a[i]);
}while(++i<size);

//do{
printf("入れ替え対照、何番目のデータ(1~%d個)?",size);
scanf("%d",&n);
//}while(n>size || !n);
//この段階で範囲制限させる時は上記2行のコメントを解除

if (i=swap_array(a,size,n)) printf("エラー>要素数%dは範囲外です\r\n",i);
else for (i=0;i<size;i++) printf("%d個目:%d\r\n",i+1,a[i]);
return 0;
}

こんな感じではだめでしょうか…。

#include <stdio.h>

unsigned int swap_array(int a[],unsigned int size,unsigned int s)
{
unsigned int temp,i=s;
if (size<s) return s;// 要素数を返す
while (i-1) temp=a[s-i+1],a[s-i+1]=a[s-i],a[s-i--]=temp;
return 0;
}
int main()
{
int a[10];
unsigned int n,i=0,size=sizeof(a)/sizeof(unsigned int);

do{
printf("%d個目のデータ?",i+1);
scanf("%d",&a[i]);
}while(++i<size);

//do{
printf("入れ替え対照、何番目のデータ(1~%d個...続きを読む

Q",which"と"which"の違いとは

関係代名詞の”,Which”とカンマのないWhichの違いとは何なんでしょうか。よく理解できていないので、教えてください。お願いします。

Aベストアンサー

(1)which:限定(制限)用法
(2), which:非制限用法
と呼びます。

前者は、一般に先行詞を「限定」するために、後者は先行詞に「追加情報」を与えるために用います。

よく使う例ですが
(1)Tom has three pens which look very expensive.
(2)Tom has three pens, which look very expensive.

(1)の方では、'pens'のうち、「高そうに見える」ものだけに話の対象を限定しています。

対して(2)の方では、トムの持っている'pens'に対して、それが「高そうに見える」という情報を付け加えています。

その結果生じる明確な違いは、
(1)の場合には、「3本の高そうなペン」以外に、「高そうではないペン」を持っている可能性があります。言い換えれば、(1)の文は「高そうなペン」の話しかしていない(限定している)ため、それ以外についてはわからないのです。

(2)の場合には、「トムは3本のペンを持っている」と言った上で「そのペンは高そうに見える」という情報を追加しているので、トムの持っているペンはその3本以外にはないという含みがあります。

(1)which:限定(制限)用法
(2), which:非制限用法
と呼びます。

前者は、一般に先行詞を「限定」するために、後者は先行詞に「追加情報」を与えるために用います。

よく使う例ですが
(1)Tom has three pens which look very expensive.
(2)Tom has three pens, which look very expensive.

(1)の方では、'pens'のうち、「高そうに見える」ものだけに話の対象を限定しています。

対して(2)の方では、トムの持っている'pens'に対して、それが「高そうに見える」という情報を付け加えています。
...続きを読む

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個分のデータを取り出...続きを読む

Qこの問題、どうしてカンマ不要なのか?

次のような英作問題がありました。
二番目の問題で、「but の前には、カンマをつけよ」と模範解答にはありました。
一番目の問題では、「andの前」には、カンマがありません。
これはどうしてなのでしょうか。

■彼女は立ち上がって窓を開けました。(andを用いて)
She stood up and opened the window.

■私はとても疲れていましたが、母を手伝いました。
I was very tired, but helped my mother.

二つとも、前節と後節の主語は同じです。
二つとも、二つの文章を結びつけています。
一見、「違いはないじゃないか」と思いました。

私が考えた2つの文章の違いは、

◇一番目の文章は、立ち上がり→窓をあけるという一連の動作であること。
◇また、一番目の文章の方が、二番目の文章と比べると…まあ、短い。

よって、一番目のandの前には、カンマがつかないのかと思いましたが…。

しかし、自信がもてません。

アドバイスを、お願いいたします。

Aベストアンサー

この問題、どうしてカンマ不要なのか?
次のような英作問題がありました。
二番目の問題で、「but の前には、カンマをつけよ」と模範解答にはありました。
一番目の問題では、「andの前」には、カンマがありません。
これはどうしてなのでしょうか。

andやbutは、等位接続詞と言って、基本は2つの同等なものをつなぎます。
Tom and Mary are married.
名前と名前をつなぎ、同等なものを結んでいます。


■彼女は立ち上がって窓を開けました。(andを用いて)
She stood up and opened the window.
→この場合、upはついていますが、stoodとopenedという動詞を2つ結んでいます。
ここにカンマを入れることは可能ですが、
その場合、彼女が立ち上がり、それからーーと、ひと呼吸あるといいますか、少しそこに時間のずれを感じさせます。
She stoop up, and opened the window.はちょっと特殊な言い方となりますね。

■私はとても疲れていましたが、母を手伝いました。
I was very tired, but helped my mother.
→これはbe動詞と一般動詞という、同じ動詞でも、種類の違うものを結んでいます。
こういう場合、
1.I was [ very tired ] and [ ( I was ) helped ]
2.I [ was very tired ] and [ I ] helped.
という2つの解釈の可能性が生じてしまいます。
ところが、カンマを入れることにより、1ではなく、2だということになるのです。
この場合カンマを入れるべきです。

以上、ご参考になればと思います。

この問題、どうしてカンマ不要なのか?
次のような英作問題がありました。
二番目の問題で、「but の前には、カンマをつけよ」と模範解答にはありました。
一番目の問題では、「andの前」には、カンマがありません。
これはどうしてなのでしょうか。

andやbutは、等位接続詞と言って、基本は2つの同等なものをつなぎます。
Tom and Mary are married.
名前と名前をつなぎ、同等なものを結んでいます。


■彼女は立ち上がって窓を開けました。(andを用いて)
She stood up and opened the window.
→この場合、up...続きを読む

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オブジェクトのデストラクタが呼び出される。

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


人気Q&Aランキング

おすすめ情報