教えてください!
fgetsでストリームから文字をline[20]に格納できたとします。
その後、lineから1文字づつ参照していき、
カンマで区切られたデータをそれぞれ別の変数に格納したいのです。
1文字づつ参照するためにはどんな関数でできますか?
getcやfgetcではできないと思うのですが・・・。

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

A 回答 (6件)

No5 の修正です。


インクリメントの場所を間違ってました。

int i;
char *p[20];

i=0;
p[i] = strtok(line, ",");
while(p[i]!=NULL){
i++;
p[i] = strtok(NULL, ",");
}
    • good
    • 0
この回答へのお礼

無事解決しました。
みなさんありがとうございます。
また何かわからないことがあったら
ここに投稿するつもりです。

お礼日時:2001/08/23 17:14

格納したあとに分割するという考え方でどうでしょうか?



int i;
char *p[20];

i=0;
p[i] = strtok(line, ",");
while(p[i]!=NULL){
p[i] = strtok(NULL, ",");
i++
}
    • good
    • 0

こんにちは、ふたたび。


VCは、離れて久しいぞな(^^;

さて、日本語(1ワード=2バイト)が入ると言う事ですね。
すると、各Cコンパイラ(・・・というか、.hに関数が準備されていると思います)ANSI C において、日本語処理は定められていないと思いました。(ウチ最新のコンパイラじゃないので、情報が古いかも・・・)
コンパイラ次第なのですがVC++5.0(Visual studio97)では、 _mbsnicmp
という関数がマルチバイトの文字比較となっているようですね。
  <mbstring.h>
を include してください。
※ただし、実際に組んだ(使用した)わけではないので、この関数がお使いの環境で可能かどうか怪しいところではあります。
ちなみに、このバージョンのこのコンパイラ以外では、全く違う名前の関数で、この機能を実現しているかもしれません。

コンパイラの種類、バージョンを補足いただければ、分かる方が居るかもしれません。
    • good
    • 0

こんにちわ



「1文字ずつ参照して・・・」の部分は下の方のヒント(回答?)で良いと思います。

で、もう一つの方法(のヒント)を。
「ある文字で区切られたデータを分けて取得」の部分ですが、
「strchr」と言う関数と「strrchr」と言う関数があります。
ここで詳細や使用方法は説明しませんが(ヘルプを見てくださいね)、
これを上手く使うと一つ一つ調べる手間は省けます。

頑張ってください。
    • good
    • 0

char line[20];



としてるのですよね。

1文字ずつでしたら、line[0]、line[1]、line[2]・・・line[19]と
いった感じで(1)文字づつ参照できます。
気をつけなければならないのは、line[n]が0x00 の場合、そこで文字は最後です。
以降のデータは、内容が保証されませんので注意してください。

もうひとつ、ヒントとして、カンマ区切りのデータでしたら、
sscanfといった関数も便利かもしれません。

がんばってください。では。
    • good
    • 0

お疲れ様です。



配列変数ですね。さて、回答というか、ヒントです

char line[20];
で、いいですかね?(char でも、int でも良いのですが)こう仮定して話します。

line[0] = 一文字目(1バイト目)
line[1] = 二文字目(2バイト目)

に格納されていますので、0、1を for文のカウンタを使用すれば、何文字目と言う感じで、扱えます。

でわでわ

この回答への補足

文字列に全角で「あ」と入っていたらどうですか?
できませんよね?
そういう場合にも対応したいのですが。

補足日時:2001/08/23 13:57
    • good
    • 0

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

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

Qカンマで区切った文字の抽出について

環境 WIN98 VC++6.0 MFC にて

”あああ,いい,うえお”
のようにカンマで区切った文字列を

”あああ” と ”いい” と ”うえお”
のように取り出し変数に格納したいのですが、どのようにすれば良いのでしょうか?

MFCの便利な関数があればお教えください。

Aベストアンサー

先の方達の回答に補足します。

strtok で要件を満しますし、私も strtok 使うと思います。
ただ、これちょっと癖が有ります。
strtok は走査したバッファの内容を書き換えてしまいます。

例えば

  char* pszToken = NULL;
  char szBuff[] = "あああ,いい,うえお";
(実際は終端 \0 が在り "あああ,いい,うえお\0" となっている)

  pszToken = strtok(szBuff, ",");

この時 szBuff の内容は "あああ\0いい,うえお\0" となり、
pszToken は "あああ" の部分の先頭を指します。
(szBuff の0バイト目)

  pszToken = strtok(NULL, ",");

第1引数 NULL は前回の strtok の続きをやる、という意味です。
2回目で szBuff の内容は "あああ\0いい\0うえお\0" となり、
pszToken は "いい" の部分の先頭を指します。
(szBuff の7バイト目)

  pszToken = strtok(NULL, ",");

3回目は szBuff の内容が "あああ\0いい\0うえお\0" のままです。
(元々在った終端 \0 に上書きしているのかも知れませんが)
pszToken は "うえお" の部分の先頭を指します。
(szBuff の12バイト目)

  pszToken = strtok(NULL, ",");
4回目は szBuff の内容は変わらず、
pszToken には NULL が返ります。
(#2さんのように、これで切り分け処理終了のロジックを書きます)


なので、元々の szBuff[] = "あああ,いい,うえお" というデータを
後でまた使いたい可能性が有るなら、strtok には別領域にコピーした
物を渡すようにしましょう。


尚、対象となるデータを CString で保持している場合は、そのまま
では渡せないので GetBuffer で内容書き換え可能なポインタを取得
するか、充分な大きさの char 配列や new 等で必要サイズ確保した
領域にコピーした物を使います。

先の方達の回答に補足します。

strtok で要件を満しますし、私も strtok 使うと思います。
ただ、これちょっと癖が有ります。
strtok は走査したバッファの内容を書き換えてしまいます。

例えば

  char* pszToken = NULL;
  char szBuff[] = "あああ,いい,うえお";
(実際は終端 \0 が在り "あああ,いい,うえお\0" となっている)

  pszToken = strtok(szBuff, ",");

この時 szBuff の内容は "あああ\0いい,うえお\0" となり、
pszToken は "あああ" の部分の先頭を指します。
(szB...続きを読む

Qfgets, sscanf, バッファ、ストリーム について

ファイルからデータを入力するのに、fscanf の代わりに fgets と sscanf を用いようと考えています。
そこで、sscanf に与えるバッファ文字列を、ファイルストリームのように扱う方法は無いものでしょうか。
例えば以下のデータファイルに対して、以下のプログラムをうまく動作させるには、どのようにすればよいでしょうか。
どうぞ、よろしくお願いします。

(データファイル test.dat)
n_data 4
1 3 8 4

(プログラム)
#include <stdio.h>

main()
{
int i, n_data, *data;
char buf[100];
FILE *fp;

fp = fopen ( "test.dat", "r" );

fgets(buf, 100, fp);
sscanf( buf, "n_data %d\n", &n_data );
data = (int *)malloc( n_data * sizeof(int) );

for( i=0; i<n_data; i++ ){
fgets(buf, 100, fp);
sscanf( buf, "%d", &(data[i]) );
}
sscanf( buf, "\n" );
close( fp );

printf( "n_data %d\n", n_data );
for( i=0; i<n_data; i++ )
printf( " %d", data[i] );
printf( "\n" );
}

ちなみに、2行の fgets(buf, 100, fp); をコメントアウトして、
"sscanf( buf," を "fscanf( fp," に変更するとうまく動作します。

ファイルからデータを入力するのに、fscanf の代わりに fgets と sscanf を用いようと考えています。
そこで、sscanf に与えるバッファ文字列を、ファイルストリームのように扱う方法は無いものでしょうか。
例えば以下のデータファイルに対して、以下のプログラムをうまく動作させるには、どのようにすればよいでしょうか。
どうぞ、よろしくお願いします。

(データファイル test.dat)
n_data 4
1 3 8 4

(プログラム)
#include <stdio.h>

main()
{
int i, n_data, *data;
char buf[100];
...続きを読む

Aベストアンサー

アプローチの仕方は色々あるだろうけど、1つの方法
----------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(){
int i, n_data, *data;
char buf[100], *p;
FILE *fp;

fp = fopen ( "test.dat", "r" );

fgets(buf, 100, fp);
sscanf( buf, "n_data %d\n", &n_data );
data = (int *)malloc( n_data * sizeof(int) );

fgets(buf, 100, fp);
p=strtok(buf, " \t\n");
for( i=0; i<n_data; i++ ){
sscanf( p, "%d", &(data[i]) );
p=strtok(NULL, " \t\n");
}
fclose( fp );

printf( "n_data %d\n", n_data );
for( i=0; i<n_data; i++ )
printf( " %d", data[i] );
printf( "\n" );


return 0;
}

アプローチの仕方は色々あるだろうけど、1つの方法
----------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(){
int i, n_data, *data;
char buf[100], *p;
FILE *fp;

fp = fopen ( "test.dat", "r" );

fgets(buf, 100, fp);
sscanf( buf, "n_data %d\n", &n_data );
data = (int *)malloc( n_data * sizeof(int) );

fgets(buf, 100, fp);
p=strtok(buf...続きを読む

Q数字列を3桁ごとにカンマで区切る方法

すいません、今授業の課題で下のような課題をもらったんです。

数字を読み込み、カンマ編集して出力する。

例) 入力:1000000 出力:1,000,000

注) メイン処理のみで製作すること
   ポインタも使わない
   入力はscanfで

三桁区切りのカンマは、後ろから入れていくということは分かるのですが、書きかたがいまいちわかりません。どなたか教えてください。お願いします。

Aベストアンサー

Cmachineという事はC言語を使うという事ですね? 言語や環境を書いておかないと適切な回答は得られませんよ。

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

#define ARRAY_SIZE 128

int main()
{
  char input[ARRAY_SIZE];
  char output[ARRAY_SIZE];
  int len;
  int i = 0;
  int j = 0;

  memset(input, 0, ARRAY_SIZE);
  memset(output, 0, ARRAY_SIZE);

  scanf("%s", input);
  len = strlen(input);

  while (i < len) {

    output[j] = input[i];
    i++;
    j++;
    if ( (len - i) % 3 == 0 ) {
      output[j] = ',';
      j++;
    }
  }

  if (output[j - 1] == ',') {
    output[j - 1] = '\0';
  }

  printf("output = %s\n", output);
  return 0;
}
-------------------------------------------------

エラーチェックが甘いけど、入力が正しければ、正常に動作すると思います。全角スペース入りなので、削除してからコンパイルしてください。

Cmachineという事はC言語を使うという事ですね? 言語や環境を書いておかないと適切な回答は得られませんよ。

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

#define ARRAY_SIZE 128

int main()
{
  char input[ARRAY_SIZE];
  char output[ARRAY_SIZE];
  int len;
  int i = 0;
  int j = 0;

  memset(input, 0, ARRAY_SIZE);
  memset(output, 0, ARRAY_SIZE);

  scanf("%s", input);
  len = strlen(input);

 ...続きを読む

Qgetcによる空白文字カウントでの問題

下記リストをWindows98、BCC5.5及び、MinGWでコンパイルして実行
する場合、/*注*/の1行をコメントアウトしますとその下のcountが
画面に表示されません。私にはこれは理解の出来ないことで、かな
り悩んでいます。どなたかお分かりになる方いらしゃいましたら、
ご教授願います。

#include <stdio.h>

int main()
{
int ch,count=0;
printf("文字を入力して下さい。\n");
while((ch=getc(stdin))!=EOF)
{
if(ch==' ')
{
count++;
}
}
/*注*/ printf("\n");
printf("count of space = %d \n",count);
return 0;
}

Aベストアンサー

getcだけではなくて、ストリーム入出力の問題のようです。昔ディスプレイがなかった時代にラインプリンタに結果を出力していましたが、その時代のなごりだと聞いたことがあります。プリンタの印刷開始の合図として改行コード(0x0a)を送っていたらしいです。
以前プログラマの仕事をしていたときに、先輩のプログラマが、
printf("\nメッセージ");
という書き方をしていたので、聞いてみたところこのような現象を回避するためだと説明されたことがあります。
前回の回答でBUGと書きましたが、BUGというより古い仕様というのが正しいのかもしれません。

Qfgetsで拾われる改行文字を削除したい

お世話になります

 C言語初心者のものです。今課題でC言語を用いたプログラミングを
Fedora上でやっています。問題は、fgetsでテキストファイルから、取得
した文字列の中から改行文字を削除できないことです。文字変数のアド
レスはわかっているのですが、終端文字に置換しようとすると、セグメ
ントエラーになってしまいます。これは如何にして解決すべきでしょう
か。よろしくお願いします。

Aベストアンサー

ポインタとかアドレスとか、C言語の用語としてあるものを別の意味に使うとまぎらわしいです。

「ポインタ」「アドレス」と言われたら、 この例なら str, str+i が思い浮びます。
「文字変数のアドレス」だと
char c ;
に対しての
&c
が思い浮びます。

配列なら「添字」、意味的には「x文字目」ですね。

> for(i=0;;i++){
> if(*(str+i)=='/n') {
> *(str+i)='\0';
> break;
> }
> }
/nが\nの間違いなら、この方法で半分正解です。もう少し広い範囲(可能なら全体)で見ないことにはなんとも言えません。
fgetsが最大文字数に達したり、ファイルの最後になったりで、strに改行文字が含まれない場合には、このループは止まりません(Segmentension Falutになって止まる)

・そのような状態になってないか、予めチェックする
・ループを終了させる仕組みを用意しておく
: forの終了条件を記述する、for中で if(*(str+i)=='\0') { break;} 等としておく、等
といった対策が必要です。


あと細かいところを言えば
・strを配列で用意したなら *(s+i)じゃなくてs[i]でいいんじゃないかな
・あるいは char *pみたいにしておいて、 iのループでなく pでループを組む( for(p=str;*p!='\0';p++) )とか。

ポインタとかアドレスとか、C言語の用語としてあるものを別の意味に使うとまぎらわしいです。

「ポインタ」「アドレス」と言われたら、 この例なら str, str+i が思い浮びます。
「文字変数のアドレス」だと
char c ;
に対しての
&c
が思い浮びます。

配列なら「添字」、意味的には「x文字目」ですね。

> for(i=0;;i++){
> if(*(str+i)=='/n') {
> *(str+i)='\0';
> break;
> }
> }
/nが\nの間違いなら、この方法で半分正解です。もう少し広い範囲(可能なら全体)で見ないことにはなんとも言えません。
fgetsが...続きを読む


人気Q&Aランキング

おすすめ情報