忙しい現代人の腰&肩のお悩み対策!

csvファイルのカンマを数えて任意の文字列を抜き出すまでは出来たのですがそこから構造体に格納するまでがこちらのサイトでも検索しましたがよくわかりません。
ご指摘のほどよろしくお願いします。
csvデータ
番号,名前,住所,電話,年齢,性別
1,佐藤,東京,1234,33,A
2,田中,,5678,22,
3,坂井,名古屋,,,B


番号,住所,電話,年齢を格納する場合
struct k_data {
char no[4];/* 出来れば番号を右詰めにしたい */
char add[20];
int tel;
int age;
} kaiin[256];
/* 文字列を抜き出す↓ */
int main(void)
{
FILE *fp1,*fp2;
char dat[256];
char *ch;
int cnt;

/* fp1 ファイルオープン */
/* fp2 ファイルクローズ */

while (fgets(dat, 256, fp1) != NULL) {
cnt = 0;
for (ch = dat; *ch != '\0'; ch++) {
if (*ch ==',') {
if (cnt == 0) {
putc(*ch, fp2);
}
if (cnt == 2) {
putc(*ch, fp2);
}
if (cnt == 3) {
putc(*ch, fp2);
}
if (cnt == 4) {
putc('\n', fp2);
}
cnt++;
} else {
if (cnt == 0) {
putc(*ch, fp2);
}
if (cnt == 2) {
putc(*ch, fp2);
}
if (cnt == 3) {
putc(*ch, fp2);
}
if (cnt == 4) {
putc(*ch, fp2);
}
}
}
putc('\0', fp2);
}
fclose(fp2);
fclose(fp1);
}

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

A 回答 (3件)

まず、取得データをファイルに書き込むのではなく、内部に格納バッファを用意してそこに一時バッファとして格納してください。


CSV仕様上、改行('\n')が要素の終端を表しますので、まず、CSVファイルから1行づつバッファに読み込み、そのバッファデータからカンマ検索実施の上各構造体メンバにセットすればよいと思います。
    • good
    • 0

 fclose 忘れてた。

    • good
    • 0

#include <stdio.h>


#include <stdlib.h>

struct k_data{
char no[4];
char add[20];
int tel;
int age;
};

int main(void)
{
FILE *fp = fopen("data.txt", "r");
struct k_data kaiin[256];
char tels[16], ages[16];
int i;

if(!fp) return 1;
for(i = 0; i < 256 ; i ++){
kaiin[i].no[0] = kaiin[i].add[0] = tels[0] = ages[0] = '\0';
if(fscanf(fp, "%[^,]%*c%*[^,]%*c%[^,]%*c%[^,]%*c%[^,]%*c%*[^\n] ",
kaiin[i].no, kaiin[i].add, tels, ages) == EOF) break;
kaiin[i].tel = strtol(tels, NULL, 10);
kaiin[i].age = strtol(ages, NULL, 10);
printf("(%4s)(%20s)(%8d)(%8d)\n",
kaiin[i].no, kaiin[i].add, kaiin[i].tel, kaiin[i].age);
}
return 0;
}
    • good
    • 0

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

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

このQ&Aを見た人はこんなQ&Aも見ています

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

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

Qファイルから読み込んだデータを構造体に格納できますか?

1レコード19バイトのファイルを
読み込む処理を行っています。

地区名10バイト
県名8バイト
改行1バイト

このデータをdouken(構造体)に格納したいのですが
>while (fgets(dou,19,fp) != NULL){
で、エラーになってしまいます。

どのようにしたら
ファイルから読み込んだデータを
構造体に格納できますか?


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

struct douken {
char tiku[10];
char ken[8];
}

main(void){

FILE *fp;
struct douken dou[100];
int i;

fp = fopen("ex3.fil","rb");

if ( fp == 0 ){
printf("can't open\n");
exit(1);
}

while (fgets(dou,19,fp) != NULL){



1レコード19バイトのファイルを
読み込む処理を行っています。

地区名10バイト
県名8バイト
改行1バイト

このデータをdouken(構造体)に格納したいのですが
>while (fgets(dou,19,fp) != NULL){
で、エラーになってしまいます。

どのようにしたら
ファイルから読み込んだデータを
構造体に格納できますか?


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

struct douken {
char tiku[10];
char ken[8];
}

main(void){

FILE *fp;
struct douken dou[100];
int i;

...続きを読む

Aベストアンサー

>>while (fgets(buffer,20,fp) != NULL){
>と、するということですか?
>その場合、
>ここのサイズは必ず4の倍数になるということですよね?
構造体を直接扱うと、アーキテクスチャやコンパイラ依存してしまいます。
32bit機なら4byteですし、16bit機なら2byte。64bit機なら8byteです。
また、コンパイラの設定によってもどのように確保されるかまったく分からないのです。
一度バッファに蓄えてからmemcpyでコピーする方が安全ですし、可搬性があります。
C言語では\0を文字列の終端文字として使用しているので、10文字格納したいなら11byte確保する必要もあります。
簡単に修正してみました。

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

typedef struct douken_ {
char tiku[11];
char ken[9];
} douken;

int main(void){
FILE *fp;
douken dou [100];
char buff [18 /* douken */ + 1 /* LF(\n) */ + 1 /* \0 */];
int i;
i = 0;

fp = fopen("ex3.fil","rb");

if ( fp == 0 ){
printf("can't open\n");
exit(1);
}

// douを\0で埋める
memset (dou , '\0' , sizeof dou);

// 一度バッファに格納
while (fgets(buff,sizeof buff,fp) != NULL){
// memcpy関数でコピー
memcpy(&dou[i],buff,10);
memcpy(&dou[i],buff+10,8);

// 構造体配列より大きなファイルを開いたときの配慮
if (i == 99) break;
i++;
}

return 0;
}

>>while (fgets(buffer,20,fp) != NULL){
>と、するということですか?
>その場合、
>ここのサイズは必ず4の倍数になるということですよね?
構造体を直接扱うと、アーキテクスチャやコンパイラ依存してしまいます。
32bit機なら4byteですし、16bit機なら2byte。64bit機なら8byteです。
また、コンパイラの設定によってもどのように確保されるかまったく分からないのです。
一度バッファに蓄えてからmemcpyでコピーする方が安全ですし、可搬性があります。
C言語では\0を文字列の終端文字として使用して...続きを読む

QCSVファイルを読み込み構造体のメンバ、"value"に格納し、その後

CSVファイルを読み込み構造体のメンバ、"value"に格納し、その後平均値を求めて構造体のメンバ、"ave"に格納し表示させたいのですが、読み込み格納している最中で、セグメンテーション違反で終了してしまいます。どなたかよろしければ教えて頂けないでしょうか。


プログラム
**************************************************

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define SIZE 64
#define FILE_NAME_00 "f_00_01.CSV"


struct Data{
double value;
double ave;
};


int main(int argc, char *argv[]) {

FILE* fp,*fo; // ファイルポインタ用
int n, i, file_size;


struct Data *dat;

if ((fp = fopen(FILE_NAME_00,"r")) == NULL) {
printf( "file open error\n" );
exit(EXIT_FAILURE);
}


fseek(fp, 0, SEEK_END);
file_size = ftell(fp);
dat = (struct Data*)malloc(file_size);

printf("malloc address= %p, file size= %d\n", dat, file_size);

fseek(fp, 0, SEEK_SET);
i = 0;


for(i=0;i<file_size;i++){
fscanf(fp,"%lf",&dat[i].value);
printf("%lf\n",dat[i].value);
i++;

}





fclose(fp);




printf("\n");
free(dat);

return 0;

}

***************************************************


f_00_01.CSV
***************************************************

2.313725
2.312810
2.314031
2.316167
2.315557
2.313725
.
.
.
.
.
***********************************************

CSVファイルを読み込み構造体のメンバ、"value"に格納し、その後平均値を求めて構造体のメンバ、"ave"に格納し表示させたいのですが、読み込み格納している最中で、セグメンテーション違反で終了してしまいます。どなたかよろしければ教えて頂けないでしょうか。


プログラム
**************************************************

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define SIZE 64
#define FILE_NAME_00 "f_00_01.CSV"


struct Data{
double value;
double ave;
};


int main...続きを読む

Aベストアンサー

おや、どこかで見覚えが・・・。

「for(i=0;i<file_size;i++){」ですが、fscanf()は1行読み込むところを file_size回(8倍)も余分に読んでいます。これではパソコンもたまったものではありませんよね。普通はファイルの終わりまで読むのが一般的です。
 また、無理してカンマのCSVファイルにしなくてもカンマが使われていないのですから、普通のファイル名でよいのではないですか。



#include <stdio.h>
#include <stdlib.h>
#define SIZE 64
#define FILE_NAME_00 "f_00_01.CSV"

struct Data{
double value;
double ave;
};

int main(void){
FILE* fp,*fo; // ファイルポインタ用
int n, i, file_size;
struct Data *dat;

if ((fp = fopen(FILE_NAME_00,"r")) == NULL) {
printf( "file open error\n" );
exit(EXIT_FAILURE);
}

fseek(fp, 0, SEEK_END);
file_size = ftell(fp);
// double + double = 16バイト。 csv fileは1行8バイト。
dat = (struct Data*)malloc(2 * file_size);
printf("malloc address= %p, file size= %d\n", dat, file_size);

fseek(fp, 0, SEEK_SET);
i = 0;
while(fscanf(fp, "%lf", &dat[i].value) != EOF) {
printf("%lf\n",dat[i++].value);
}

fclose(fp);
free(dat);

return 0;
}

おや、どこかで見覚えが・・・。

「for(i=0;i<file_size;i++){」ですが、fscanf()は1行読み込むところを file_size回(8倍)も余分に読んでいます。これではパソコンもたまったものではありませんよね。普通はファイルの終わりまで読むのが一般的です。
 また、無理してカンマのCSVファイルにしなくてもカンマが使われていないのですから、普通のファイル名でよいのではないですか。



#include <stdio.h>
#include <stdlib.h>
#define SIZE 64
#define FILE_NAME_00 "f_00_01.CSV"

struct Data{
double val...続きを読む

Qカンマ区切りのデータを配列に読み込みたい

趣味でゲームを製作しているのですが、その中で、
マップデータのテキストファイルを二次元配列に読み込むようにしています。
データファイルは、カンマ区切りで、例えば、
1,2,3,4,5
5,4,3,2,1
1,2,3,4,5
というようになっています。

fp=fopen(path,"r");
for(j=0; j<3; j++)
{
for(i=0; i<5; i++)
{
char c;
do{c=(getc(fp));}
while(c==','||c=='\n'||c=='\r');
map[j][i] = c-'0';
}
}

配列の各要素に読み込む中身が、0~9など1文字に限られている場合、このgetc()を使う方法で問題ないのですが、0~255など、文字数がまちまちになると、1文字を取り出すgetc()ではできなくなってしまいます。

これがどうすれば可能になるのか、情けないのですがちょっと思いつかないので、アドバイスを頂ければ幸いです。

Aベストアンサー

少し手を入れたらできそうですね。


{
char c;
do{c=(getc(fp));}
while(c==','||c=='\n'||c=='\r');
//-----------追加-----ここから
// int calc; の宣言要
calc = 0;
do { calc = (c - '0') + (calc*10);}
while(isdigit(c=getc(fp)));
//-----------追加-----ここまで
map[j][i] = calc;
}

Qcsvファイルをfscanfで読み込むと変な文字が出てきます

csvファイルをfscanfで読み込もうとしているのですが
どうしてもおかしな文字が混じってしまいます

例えばcsvファイルのデータが

abc,efg
となっているとします

これを読み込みprintfで表示すると
abc"" efg""

というように表示されてしまいます

csvファイルを普通に開いてもこのような文字はありません
一体どこから沸いて出てくるのでしょうか?

%[^]を使って不要な文字を読み込まないように
%[^"]と記述しましたが
エラー番号c2143とc2059が出てしまいます

何か解決方法はございませんでしょうか?
よろしくお願いします。

Aベストアンサー

まずは、scanfの仕様をマニュアルなどでよく確認しましょう。

> while( ( ret = fscanf( fp, "%[^,],%[^,],%[^,],%[^,],%s", s, &n1, &n2, &f1, &f2 ) ) != EOF ){

最初の%[^,]に対して 「char型の配列」s で受けている(正解)のに、2番目以降が 「char型の配列へのポインタ」&n1, &n2 ...で受けています。これらに&は必要ありません。
手元のgccの実装では、配列のアドレスと、その配列へのポインタのアドレスがたまたま同じだったため、「正常」に動作しました。しかし、これがmalloc等で確保した領域への「char型へのポインタ」と、「『char型のポインタ』へのポインタ」だった場合は違うアドレスになり、正常に動作しません。

次にfscanfの取り込み方に関してです。
[^,]とした場合、**改行文字も取り込みの対象になります**。なので、2行目以降のsには、前入力行で取り込まれなかった改行文字が先頭に付くことになります。
また、1行にカンマが4つ無かった場合は、n1,n2,f1で「その行の改行文字まで+次の行の最初のカンマまで」を取り込みます。
sに改行コードを入れないために「fscanf( fp, " %[^\n,]....」と%の前にスペースを置いて、0個以上の空白文字(改行文字も含む)を読み飛ばします。カンマが足りないときのn1,n2,f1の方は[^\n,]として改行も含まない文字に追加します。

最後に、fscanfの戻り値です。
scanf系では、最終的に取り込んだ値の数を返します。
今回の場合、最後の行のあとに、残った改行がsに入るので、ret=1になります。EOFになるのは、その次のループになります。
一応、上の書式変更で「最後の行の後の改行文字をsに取り込む」ということはなくなりますが、ret==5でない時は正常な取り込みではないので、なんらかのエラー処理が必要でしょう。

fscanfは結構やっかいです。
上の改行もそうです。
取り込みエラーでもファイルの読み込み位置が変わらないので、次のループでまたエラーになる、といったこともあります。
1行単位で処理したい場合は、fgetsで1行読み込み→sscanfで処理 というのが常套手段です。

確認に使ったファイルを貼り付けておきましたので、修正前と修正後でどんな風に動いているか、ご自身で確認してみてください

入力:abc.csv
ab1,ef2,ab3,af4,ab5
bb1,bf2,bb3,bf4
cb1,cf2,cb3,cf4,cb5
zb1,zf2,zb3,zf4,zb5


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

int main(void)
{
FILE *fp;
char *fname = "abc.csv";
/*char s[100];*/
char *s = (char*)malloc(100); /* 比較のため、mallocでの領域確保 */
char n1[100];
char n2[100];
char f1[100];
char f2[100];
char buf[600]; /* fgets用 */
int ret;
int i=0;

fp = fopen( fname, "r" );
if( fp == NULL ){
printf( "%sファイルが開けません\n", fname );
return -1;
}

printf( "s=%p:&s=%p\nn1=%p:&n1=%p\nn2=%p:&n2=%p\nf1=%p:&f1=%p\nf2~%p:&f1=%p\n",
s, &s, n1, &n1, n2, &n2, f1, &f1, f2, &f2 );
/*↓ 1: 修正前, 0:修正後 */
#if 0
while( ( ret = fscanf( fp, "%[^,],%[^,],%[^,],%[^,],%s", s, n1,n2,f1,f2 ) ) != EOF ){
#else
while( fgets( buf,600, fp ) != NULL ) {
ret = sscanf( buf, " %[^,],%[^\n,],%[^\n,],%[^\n,],%s", s, n1,n2,f1,f2 ) ;
#endif
if ( ret != 5) {/* エラー処理 */ }

i ++ ;
printf( "No.%d::\nret=%d\n", i,ret );
printf( "s =%s\nn1=%s\nn2=%s\nf1=%s\nf2=%s\n", s, n1, n2, f1, f2 );
}

fclose( fp );
free(s);
return 0;
}

まずは、scanfの仕様をマニュアルなどでよく確認しましょう。

> while( ( ret = fscanf( fp, "%[^,],%[^,],%[^,],%[^,],%s", s, &n1, &n2, &f1, &f2 ) ) != EOF ){

最初の%[^,]に対して 「char型の配列」s で受けている(正解)のに、2番目以降が 「char型の配列へのポインタ」&n1, &n2 ...で受けています。これらに&は必要ありません。
手元のgccの実装では、配列のアドレスと、その配列へのポインタのアドレスがたまたま同じだったため、「正常」に動作しました。しかし、これがmalloc等で確保した領域への...続きを読む

Q構造体でのファイル操作

1 2 3
1 2 3
1 2 3
1 2 3

みたいに書き込まれた
txtデータを構造体でよみこみたいのですけどうまくいきません
プログラムはこんなかんじです
int i=0;
FILE *fp;
fp = fopen("Data.txt","r");
while (fscanf(fp, "%d,%d,%d",a.no[i],a.A[i],a.B[i] ) != EOF){
i++;
}
fclose(fp);

a.noが1列目で
a.Aが2列目で
a.Bが3列目です


Debug assertion failed 
と表示されます
どうしてでしょうか?

Aベストアンサー

既に回答付いていますが…

int a;
scanf("%d",a);

という書き方が問題ない…と思いますか?
この時scanf()に渡されるのは、変数aの値(未初期化なので不定な値)で、scanf()はその不定な値をint型の値を格納するアドレスとして使います。
# "%d"で指定されていますからね。

さて、あなたのコードはどうでしょう?

あとは…「半角スペース区切り」なのか「カンマ区切り」なのかも注意が必要でしょうけど。

QCSVファイルの内容を構造体に格納したい(Unix使用)。

こんにちは。私は30代の男性です。
「名前」「身長」「体重」が記載されたCSVファイルの内容を読み取って、構造体の「name」「height」「weight」に格納するプログラムを作っています。CSVの内容は
A,175,80
B,167,89
C,155,45



Z,188,70
だと仮定します。数値が読み取れているか、下記のように「tp = strtok(file_image, ",\n" );」の前後に「printf("%s\n", file_image);」を置いてみたら、strtok前では全て表示されるのに、strtok後では「ABC」しか表示されません。これでは全てのデータを構造体に格納できないので、困っています。
1.どのようにすれば、数字も取り出せる(読み取れる)でしょうか?
2.効率よく構造体に格納するには、どのようにしたらよいでしょうか?

アドバイスを頂ければ幸いです。宜しくお願いいたします。

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
int main(int argc, char *argv[])
{
FILE *fp = NULL;
int rtn = 0;
if ((fp = fopen(argv[1], "r")) == NULL)
{
printf("ファイルオープンに失敗しました。\n");
return 1;
}
if (argc != 2)
{
printf("ERROR: オプションの数に過不足があります。\n");
return 1;
}
rtn = change_csv(fp);
return 0;
}
int change_csv(FILE *fp)
{
int i;
int j;
char file_image[256]; /* 読み込んだ先のメモリの領域 */
char *tp;
for (i = 0; i <= 256; i++)
{
if (fgets(file_image, 256, fp) == NULL)
{
if (ferror(fp) != 0)
{
printf("ERROR: 読み込みに失敗しました。\n");
return 1;
}
}
if (feof(fp) != 0)
{
break;
}
printf("%s\n", file_image);
tp = strtok(file_image, ",\n" );
printf("%s\n", file_image);
}
fclose(fp);
return 0;
}

こんにちは。私は30代の男性です。
「名前」「身長」「体重」が記載されたCSVファイルの内容を読み取って、構造体の「name」「height」「weight」に格納するプログラムを作っています。CSVの内容は
A,175,80
B,167,89
C,155,45



Z,188,70
だと仮定します。数値が読み取れているか、下記のように「tp = strtok(file_image, ",\n" );」の前後に「printf("%s\n", file_image);」を置いてみたら、strtok前では全て表示されるのに、strtok後では「ABC」しか表示されません。これでは全てのデータを構...続きを読む

Aベストアンサー

★過去に似たような質問がありました。
・その質問は『改ページ』で区切られた文字列を読み込むにはどうすればよいか?
 というものでした。今回は CSV ですが『改ページ』の部分を『カンマ文字』に
 指定すれば文字列を分割できます。
・そのほか細かい点をアドバイスしますと
 (1)main 関数の『FILE *fp = NULL;』や『int rtn = 0;』は代入後に参照しているため初期化の必要はありません。
 (2)main 関数の『if (argc != 2){ … }』のリターンの前で『fclose(fp);』を記述しておきましょう。
 (3)change_csv 関数に『fclose(fp);』がありますが、main 関数で統一させると分かりやすくなります。
 (4)change_csv 関数で『fgets』のバッファ容量は『fgets(file_image,sizeof(file_image),fp)』とすると良いでしょう。
 (5)change_csv 関数で『feof』を使うのならば『i』カウンタは必要ない気がします。
  while ( fgets(file_image,sizeof(file_image),fp) != NULL ){
   /*
   行単位で CSV データを分割して構造体にセットする処理
   */
  }
  if ( feof(fp) ){
   printf( "SUCCESS: 正常に読み込みました。\n" );
  }
  else if ( ferror(fp) ){
   printf( "ERROR: 読み込みに失敗しました。\n" );
  }
  else{
   printf( "ERROR: 不明なエラーで読み込みを中止しました。\n" );
  }
 (6)『strtok』を使うのなら次のようにします。→分かりやすくするためループしない記述です。
  char *array[ 3 ];
  char *token = " ,\t\r\n";
  
  array[ 0 ] = strtok( file_image, token );…名前(name)
  array[ 1 ] = strtok( NULL, token );……身長(height)
  array[ 2 ] = strtok( NULL, token );……体重(weight)

最後に:
・『strtok』もよいがカンマ文字の前後にタブやスペースがないならば『strchr』関数でも分割できます。
 その方法が下の『参考URL』でサンプルを載せています。どうぞ参考に。
・以上。頑張って下さい。私も30代の男性です。

参考URL:http://oshiete1.goo.ne.jp/qa2749340.html

★過去に似たような質問がありました。
・その質問は『改ページ』で区切られた文字列を読み込むにはどうすればよいか?
 というものでした。今回は CSV ですが『改ページ』の部分を『カンマ文字』に
 指定すれば文字列を分割できます。
・そのほか細かい点をアドバイスしますと
 (1)main 関数の『FILE *fp = NULL;』や『int rtn = 0;』は代入後に参照しているため初期化の必要はありません。
 (2)main 関数の『if (argc != 2){ … }』のリターンの前で『fclose(fp);』を記述しておきましょう。
 (3)chan...続きを読む

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が...続きを読む

QC言語で複数列のデータを1列のみ読み込みたい

行m列の任意のデータの処理を行うプログラムで,
列ごとの統計を行うためにm列目のデータを取り出したいのですが,うまくいきません.
どのようなコードを書けばいいでしょうか?

自分で作ってみたのは以下のようなプログラムです(ファイルを開いて→m列目の読み込みの部分)
EOFを使っているためか,行数のiには全データ数が入ってしまいます.


void main (void)
{
FILE* fp;

int i, j;
i=0, j=0;

char FilePath[500];
char Folder[100];
char File[50];

printf("Folder Name:");
scanf("%s",&Folder);

printf("File Name:");
scanf("%s",&File);

sprintf(FilePath,"%s/%s",Folder,File);

if(( fp = fopen (FilePath,"r")) == NULL){
printf("cannot open '%s'\n", FilePath);
exit(1);
} //ここまではうまく動きます


while (fscanf(fp, "%lf", &A[i][0]) != EOF{
i++;
}
while (fscanf(fp, "%lf", &A[0][j]) != EOF){
j++;
}

printf("A[%d][%d]", i, j);
int n, m;              //n,mはこの後for文で使いたいので登場してもらいました
printf("input 'n':");
scanf("%d", &n);
printf("input 'm':");
scanf("%d", &m);

行m列の任意のデータの処理を行うプログラムで,
列ごとの統計を行うためにm列目のデータを取り出したいのですが,うまくいきません.
どのようなコードを書けばいいでしょうか?

自分で作ってみたのは以下のようなプログラムです(ファイルを開いて→m列目の読み込みの部分)
EOFを使っているためか,行数のiには全データ数が入ってしまいます.


void main (void)
{
FILE* fp;

int i, j;
i=0, j=0;

char FilePath[500];
char Folder[100];
char File[50];

printf("Folder Name:");
scanf("%s",&...続きを読む

Aベストアンサー

>どのようなコードを書けばいいでしょうか?

 http://okwave.jp/qa/q7114321.html #3

 読み込み時に配列に格納しないで、
 文字列として1行読み込んでから、(数値化し)配列に格納する例です。

 「m列目のデータ」の前には、m - 1 個の空白があるので、それをカウントし数値化します。
 (ただし、文字列には空白が連続しないこと)

 「実数」を「整数」に、「コンマ」を「空白」に置き換えればよいかと。

 http://www.bohyoh.com/CandCPP/C/Library/fgets.html
 http://www.bohyoh.com/CandCPP/C/Library/atoi.html

QC言語のポインターに関する警告

line[100]で
「1」が格納されていたら「a」
「2」が格納されていたら「b」
「3」が格納されていたら「c」
とout[100]に代入する関数を作りたいのですが
コンパイルすると関数の部分で
warning: assignment makes integer from pointer without a cast
という警告がでます。
ポインターは使っていないのですが、ポインターに関する警告が出ているようで困っています。
どこが悪いのかまったくわからなくて作業が完全に止まってしまいました。
解決法をおしえてください。お願いします。

/*宣言*/
int=i; /*main関数内のfor文で使用*/
char line[100], out[100];
void change(int);

/*関数*/
void change(int i)
  {
   if(line[i]=='1'){
    out[10]="a\0"
   }if(line[i]=='2'){
    out[10]="b\0";
   }if(line[i]=='3'){
    out[10]="c\0"
}
}

line[100]で
「1」が格納されていたら「a」
「2」が格納されていたら「b」
「3」が格納されていたら「c」
とout[100]に代入する関数を作りたいのですが
コンパイルすると関数の部分で
warning: assignment makes integer from pointer without a cast
という警告がでます。
ポインターは使っていないのですが、ポインターに関する警告が出ているようで困っています。
どこが悪いのかまったくわからなくて作業が完全に止まってしまいました。
解決法をおしえてください。お願いします。

/*宣言*/
int...続きを読む

Aベストアンサー

>    out[10]="a\0"
>    out[10]="b\0";
>    out[10]="c\0"

"a\0"や"b\0"や"c\0"は「charへのポインタ」ですよ。

out[10]は「char」ですから「記憶域が小さい整数(つまり、charに)に、ポインタを代入すると、値が失われるぞ」と警告が出ます。

void change(int i)
  {
   if(line[i]=='1'){
    out[10]='a';
   }if(line[i]=='2'){
    out[10]='b';
   }if(line[i]=='3'){
    out[10]='c';
}
}
または
void change(int i)
  {
   if(line[i]=='1'){
    out[10]=0x61; /* aのASCIIコード */
   }if(line[i]=='2'){
    out[10]=0x62; /* bのASCIIコード */
   }if(line[i]=='3'){
    out[10]=0x63; /* cのASCIIコード */
}
}
と書きましょう。

>    out[10]="a\0"
>    out[10]="b\0";
>    out[10]="c\0"

"a\0"や"b\0"や"c\0"は「charへのポインタ」ですよ。

out[10]は「char」ですから「記憶域が小さい整数(つまり、charに)に、ポインタを代入すると、値が失われるぞ」と警告が出ます。

void change(int i)
  {
   if(line[i]=='1'){
    out[10]='a';
   }if(line[i]=='2'){
    out[10]='b';
   }if(line[i]=='3'){
    out[10]='c';
}
}
または
void change(int i)
  {
   if(l...続きを読む

Q構造体とfscanf

ファイルをfscanfを使って文字列を構造体に格納して読み込みたいのですが読み込み方の記述方法がわか

りません。
どのようにしたら読み込めますか?

以下ソース

---ソース---
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct info //1回目の呼び出し方法
{
char name[20];
char mb[20];
}deta;

struct info2 //2回目の呼び出し方法
{
char *name;
char *mb;
}deta2;

struct info3 //3回目の呼び出し方法
{
char *name[6];
char *mb[6];
}deta3;

void main(void){

FILE *fp;

fp=fopen("yasa.txt","r+");
while( !feof( fp ) ){
fscanf( fp, "%s %s",deta.name,deta.mb );
printf("%s %s\n",deta.name,deta.mb);
}
rewind( fp );
//2回目の呼び出し方法での記述の仕方がわからない
rewind( fp );
//3回目の呼び出し方法での記述の仕方がわからない

fclose(fp);

}


---yasa.txtの内容---
オレンジ ●
みかん ●
いちご ×
もも ●
ぶどう ×
キウイ ●

ファイルをfscanfを使って文字列を構造体に格納して読み込みたいのですが読み込み方の記述方法がわか

りません。
どのようにしたら読み込めますか?

以下ソース

---ソース---
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct info //1回目の呼び出し方法
{
char name[20];
char mb[20];
}deta;

struct info2 //2回目の呼び出し方法
{
char *name;
char *mb;
}deta2;

struct info3 //3回目の呼び出し方法
{
char *name[6];
char *mb[6];
}deta3;

void main(void){

FILE *fp;

fp=fop...続きを読む

Aベストアンサー

>//2回目の呼び出し方法での記述の仕方がわからない

deta2はポインタ変数しか持っていませんのでmalloc()などで必要な領域を確保してから、
その場所(ポインタが指している先)に読み込んで下さい。
問題は「確保するべき領域のサイズが判らない」ということですが…。
char ReadTemp1[100],ReadTemp2[100];
とかを用意して、
fscanf( fp, "%s %s",ReadTemp1,ReadTemp2 );
deta2.name = malloc(strlen(ReadTemp1)+1); //'\0'の分が必要
strcpy(deta2.name, ReadTemp1);
deta2.mb = malloc(strlen(ReadTemp2)+1); //'\0'の分が必要
strcpy(deta2.mb, ReadTemp1);
という感じで入れます。
# 使い終わった後の開放を忘れずに。
ちなみにdeta2は1個分子かありませんから、続きのデータは読めません。
detaと同じように、その場で使うだけならその都度開放して下さい。

deta3は、ポインタの配列が6個分ありますからそれぞれに領域確保して読み込ませておくこともできるでしょう。
やり方自体はdata2の時のように作業用領域に読み込んでメモリ確保して、コピーして…の繰り返しです。

>//2回目の呼び出し方法での記述の仕方がわからない

deta2はポインタ変数しか持っていませんのでmalloc()などで必要な領域を確保してから、
その場所(ポインタが指している先)に読み込んで下さい。
問題は「確保するべき領域のサイズが判らない」ということですが…。
char ReadTemp1[100],ReadTemp2[100];
とかを用意して、
fscanf( fp, "%s %s",ReadTemp1,ReadTemp2 );
deta2.name = malloc(strlen(ReadTemp1)+1); //'\0'の分が必要
strcpy(deta2.name, ReadTemp1);
deta2.mb = malloc(strlen(ReadTemp2)+1); ...続きを読む


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング