テキストファイルの読み込みで質問したいのです。
下記のソースを書いた場合、カンマ区切りでファイルを
読み込み、変数に渡す事が出来ますが、それが"|"区切りだった場合は
どのような形で書くべきでしょうか?

FILE *in_file;
char myName1[];
int myName2;

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

fscanf(in_file,"%s,%d",myName1,&myName2); /*区切り文字:*/
printf("name1%s name2%d\n",myName1, myName2);

fclose(in_file);

読込みたい情報に合わせて、ソースを下記のように変更しました。
fscanf(in_file,"%s|%d",myName1,&myName2); /*区切り文字:*/
テキストファイルの内容は、 ABC|123 です。
上記の条件だと、myName1に"ABC|123"となってしまいます。
カンマ区切りのソースに直して、データもカンマ区切りに直すと、
myName1=ABC
myName2=123
となるのですが、"|"区切りは、初めてなのでうまく出来ないのです。

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

A 回答 (2件)

ちょっとあっさりし過ぎた回答だったので、一応、解説もしておきます。



参考URLに linux の日本語訳されたマニュアルを示しておきます。
そこの「変換」の章の s の部分を読んでください。今回のことに
からむ部分を引用すると、

  * * *

文字列の入力は、 ホワイトスペースまたは最大フィールド幅(ふ
たつのうち最初に 生じたもの)によって中止される。

  * * *

ということです。

どの開発環境を使っているかによると思うのですが、大体同じ仕様
になってると思ってました。なので、"|" が "," でも期待通りの
動きをしないと思うのですが、senna13 さんがお使いの開発環境は
カンマだけ、特別扱いしているようですね。

参考URL:http://www.linux.or.jp/JM/html/LDP_man-pages/man …
    • good
    • 0
この回答へのお礼

ありがどうございました。
いやー、自分も長い事色々なプログラムをしていたのですが、
なにせ、現在の環境には、リファレンスって物がなくて・・・・
本当にありがどうございます。
後は、全てクリア出来る問題ばかりなので、自分で処理します。

お礼日時:2001/04/23 16:08

fscanf(in_file, "%[^|]|%d", myName1, &myName2);



です。
    • good
    • 0

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

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

Qwsprintf( ポインタ , "%d" , "123" );

char str[100];
char *ptr;

wsprintf(str, "%d", "1234567");

wsprintf(ptr, "%d", "1234567");
について、
TextOut(hDC,0,10,str,lstrlen(str));
TextOut(hDC,0,30,ptr,lstrlen(ptr));
で出力したいんだけど、str ならできたけど、
ptr の方が文字化けしていました。

lstrlen(ptr); がいけないのかと思って、
その値を調べたら 0 でした。

strlen( ) はポインタに対応していると思いました。

#include <iostream.h>
main(){
char *p = "あいう";
cout << strlen(p);
}

で 6 だったから。
Win32 の lstrlen( ) はポインタに対応していないんですか?

Aベストアンサー

> new char[100];
この場合、char 型で、100個分確保して、そのポインタが返ります
new int[50] だったら int 型50個分
もちろん、型だけでなく、クラスも指定出来ます。
new string[50]

> 0065FE08, 0065FE0C, 0065FE10
> で、&ptr が 0065FE00 だったとすると、
> (ptr+2) = "aaa";
*(ptr+2) = "aaa"; の間違いですよね^^;

> としたら、sonota[] の値が変更されてしまうしいうことですね?
変更されますが、変更される値は"aaa"のポインタが、sonata[0]以降に格納されます。

書き換える先が、システムの領域だったら、「不正なアクセス」が起きて、プログラムが落ちます。Linuxだと「Segmentation fault」です。

後、配列とポインタは同じものと思っておいても通常差しつかえありません。array[a] は *(array + a) の様に解釈されます。そのため

int array[3] = { 1,2,3 };
printf("%d, %8x\n", array[0], &array[0]);
printf("%d, %8x\n", 0[array], &0[array]);
printf("%d, %8x\n", array[1], &array[1]);
printf("%d, %8x\n", 1[array], &1[array]);
printf("%d, %8x\n", array[2], &array[2]);
printf("%d, %8x\n", 2[array], &2[array]);

を実行してみてください。ただし、わかりにくくなるトリッキーな書き方なので、使わないのが普通です。

> new char[100];
この場合、char 型で、100個分確保して、そのポインタが返ります
new int[50] だったら int 型50個分
もちろん、型だけでなく、クラスも指定出来ます。
new string[50]

> 0065FE08, 0065FE0C, 0065FE10
> で、&ptr が 0065FE00 だったとすると、
> (ptr+2) = "aaa";
*(ptr+2) = "aaa"; の間違いですよね^^;

> としたら、sonota[] の値が変更されてしまうしいうことですね?
変更されますが、変更される値は"aaa"のポインタが、sonata[0]以降に格納されます。

書き換える先...続きを読む

Qprintf( "%d", i % 10 );で?

int count;
int i;
scanf( "%d", &count );
for( i = 0 ; i < count ; i++ )
printf( "%d", i % 10 );「iを10で割った余り」だそうです。
i%5とした場合、 
 仮に5と入力すれば、01234と表示すると思いますが、
何でiを5で割れば5進数みたいにコンピュータが認識するのですか?
理論だけ勉強中で、実際試したことがありません? 
よろしくお願いします。

Aベストアンサー

例えば、246を例に考えてみます。

246を5で割ると49で余りが1

これは書き換えると
246 = 49x5 + 1 という事ですね。

次に49について同様に行なうと
49を5で割ると9で余りが4

これは書き換えると
49 = 9x5 + 4という事ですね。

最初の結果とあわせると、
246 = 9(x5x5) + 4(x5) + 1
という事ですね。

同様に9についても計算すると

246 = 1(x5x5x5) + 4(x5x5) + 4(x5) + 1

となります。


5で割った答えと5で割った余りは、5進数で一つ上の桁へ移せる部分とその桁に残る部分を分けている事になります。
10進数でも32を考えた時、30の部分は上の桁に移せる部分で(10で割った答え部分)2はその桁に残る部分(2 = 32 % 10)ですよね。

Qint i,j; \n i=0,j=5;

int i,j;
i=0;
j=5:
と書いてあるソースは普通ですが、
int i,j;
i=0,j=5:
と書いてあるソースもあります。
後者はC++の正しい書式ですか?

カンマ演算子というのは後者のカンマのことですか?

Aベストアンサー

 正しい書式です。

i=0,j=5;
 における、「,」をカンマ演算子といいます。2項の演算子です。カンマで区切られた演算を「左から順番に」実行し、最後の演算を結果として返します。
 したがって、例の文であれば、i=0を実行し、次にj=5を実行。そして、j=5の結果の5を結果として返します。
 ・・・
 が、本来的には、あまり、例のような使い方はしませんね。よく見られるのは、次のような場合です。

 for (i=0,j=0 ; i < 50 ; ++i,++j) {

 のような形でよく見られます。for文の各式は、一つの式でなければならないので、こんな書き方をするわけです。初期化と更新部が一つにまとまり、ループが読みやすくなるのが利点かな。

QSendMessage(hW,WM_CREATE,0,0);を

SendMessage(hW,WM_CREATE,0,0);
を実行するとシステムがWM_DOWNやWM_CHARを発行しなくなるみたいです
というのはそれ以降キー入力を無視するようになるのです
いったんアプリをアイコン化してウィンドウ化するとWM_DOWNやWM_CHARを発行するようになります
WM_CREATEを送ってもWM_DOWNやWM_CHARを発行しなくなるのを阻止するために何か方法はないでしょうか?

Aベストアンサー

>プログラムのイニシャライズのために送ったのですが送らないで住むプログラムに変更しました

普通はそんな方法はとりません。
システムが何をするか分からないからです。

自分でメッセージを定義して、初期化処理を行うようするためのメッセージを送るほうが無難です。
WM_CREATEと同じ処理を初期化処理として行わせたいのであれば、初期化処理を関数化して自分で定義したメッセージでも呼び出せばいいのですし。


>作ったプッシュボタンを押してシステムがWM_COMMANDを送ってきた後キー関係のメッセージを送ってくれなくなります

プッシュボタンがキーボードフォーカスを持ってのるでは?

ボタンがキーボードフォーカスを持っていてもキー関連のメッセージを親ウィンドウが受け取りたいのであれば、サブクラス化をするしかないでしょう。

Qscanf("%s", &gakusei[i].shimei);&以降のコラボが?

プログラムは以下です。
#include <stdio.h>
#include <string.h>

/* 学生の人数 */
#define GAKUSEI_NUM 3

/* 構造体の定義 */
struct TestKekka
{
char shimei[80];
int kokugo;
int sugaku;
int eigo;
};
int main(int argc, char* argv[])
{
int i,heikin;
/* 構造体の配列の宣言 */
struct TestKekka gakusei[GAKUSEI_NUM];

/* 学生のデータ入力する */
for (i = 0; i < GAKUSEI_NUM; i++)
{
printf("氏名:");
scanf("%s", &gakusei[i].shimei);
printf("国語の得点:");
scanf("%d", &gakusei[i].kokugo);
printf("数学の得点:");
scanf("%d", &gakusei[i].sugaku);
printf("英語の得点:");
scanf("%d", &gakusei[i].eigo);
printf("---------------\n");
}
------------------------------------------------------------------------------------------
 プログラムは以上ですが、

/* 学生のデータ入力する */
for (i = 0; i < GAKUSEI_NUM; i++)
{
printf("氏名:");
scanf("%s", &gakusei[i].shimei);
------------------------------------------------------------------------------------------
以上のscanf("%s", &gakusei[i].shimei);の&gakusei[i].shimeiの部分がよくわからないのですが!?

&はアドレス
gakusei は 配列変数名
[i]はint型
.は構造体メンバー演算子でshimeiを結び付けている?ここもいまいちですが!?
 
 以上のコラボレーションをうまくご説明がしていただけるお方がおられましたら、
 ご教授のほどをよろしくお願いいたします。

プログラムは以下です。
#include <stdio.h>
#include <string.h>

/* 学生の人数 */
#define GAKUSEI_NUM 3

/* 構造体の定義 */
struct TestKekka
{
char shimei[80];
int kokugo;
int sugaku;
int eigo;
};
int main(int argc, char* argv[])
{
int i,heikin;
/* 構造体の配列の宣言 */
struct TestKekka gakusei[GAKUSEI_NUM];

/* 学生のデータ入力する */
for (i = 0; i < GAKUSEI_NUM; i++)
{
printf("氏名:");
scanf("%s", &gakusei[i].shimei);
printf("国語の得点:");
scanf...続きを読む

Aベストアンサー

> &gakusei[i].shimeiの部分がよくわからないのですが!?


1. gakuseiは、タグ名TestKekka構造体の配列(要素数は、0~2の3個)
2. タグ名TestKekaは、shimei[80],kokugo,sugaku,eigoのメンバ変数で構成されている。
3. 構造体のメンバ shimeiは、char型変数の配列(要素数は、0~79の80個)

4. gakusei[i]は、gakusei[0]~gakusei[2]のいずれか
5. gakusei[i].shiemeiは、gausei[i]のメンバshimei[80]の先頭アドレス


 以上は、メモリ上に下記の様に配置されています(※1)
 変数i は0~2のいずれかなので、
 gakusei[i].shiemeiは下記右側の矢印部分のいずれかになります。
 (既に回答がついている様に、shimei[80]は配列なので
   先頭アドレスは&が付かないgakusei[i].shimeiになります。)

――――――――― shimei[ 0](char型) ←ここがgakusei[0].shimeiの場所(アドレス)
    ↑     shimei[ 1](char型)
 この範囲が     ……
  gakusei[0]   shimei[79](char型)
    │     kokugo(int型)
    ↓     sugaku(int型)
――――――――― eigo(int型)
――――――――― shimei[ 0](char型) ←ここがgakusei[1].shimeiの場所(アドレス)
    ↑     shimei[ 1](char型)
 この範囲が     ……
  gakusei[1]   shimei[79](char型)
    │     kokugo(int型)
    ↓     sugaku(int型)
――――――――― eigo(int型)
――――――――― shimei[ 0](char型) ←ここがgakusei[2].shimeiの場所(アドレス)
    ↑     shimei[ 1](char型)
 この範囲が     ……
  gakusei[2]   shimei[79](char型)
    │     kokugo(int型)
    ↓     sugaku(int型)
――――――――― eigo(int型)


 (※1)正確には異なる可能性がありますが、今回の説明では問題ないと考えます。

> &gakusei[i].shimeiの部分がよくわからないのですが!?


1. gakuseiは、タグ名TestKekka構造体の配列(要素数は、0~2の3個)
2. タグ名TestKekaは、shimei[80],kokugo,sugaku,eigoのメンバ変数で構成されている。
3. 構造体のメンバ shimeiは、char型変数の配列(要素数は、0~79の80個)

4. gakusei[i]は、gakusei[0]~gakusei[2]のいずれか
5. gakusei[i].shiemeiは、gausei[i]のメンバshimei[80]の先頭アドレス


 以上は、メモリ上に下記の様に配置されています(※1)
 変数i は0~2のいずれかなので、
...続きを読む


人気Q&Aランキング

おすすめ情報