FPに関する口コミや質問

 
過去の質問
2009年8月
2009年7月
2009年6月
2009年5月
2009年4月
2009年3月
2009年2月
2009年1月
2008年12月
2008年11月
2008年10月
2008年9月
2008年8月
2008年7月
2008年6月
2008年5月
2008年4月
2008年3月
2008年2月
2008年1月
2007年12月
2007年11月
2007年10月
2007年9月
2007年8月
2007年7月
2007年6月
2007年5月
2007年4月
2007年3月
2007年2月
2007年1月
2006年12月
2006年11月
2006年10月
2006年9月
2006年8月
2006年7月
2006年6月
2006年5月
2006年4月
2006年3月
2006年1月
2005年8月
2005年5月
2004年6月
簿記

質問

以前質問したものとほぼ同様の質問ですが、memcpyを使用して完成させたいと思っています。
memcpyは初めて使用するので、ご指導お願いします。
ファイルに書かれた任意のASCIIコード文字列(A~Cを使用)を読み込んで、構造体に文字種ごとに格納し、格納した結果を文字種ごとに一行で標準出力するプログラムを作成中です。
例としてABBCCCとファイルに書かれていたらtypedef struct {char a[1];char b[2];char c[3];} in_dataの構造体にAはchar aへBはchar bへと格納していく。
表示はA=AB=BBC=CCCのようにしたいと考えています。
あとプログラム上Switch文で'A','B','C'とわけて、その処理中で構造体のメンバに格納したいと考えています。
また、ファイルに小文字や記号などが書き込まれていた場合を想定してエラーとして出力したいと考えています。
エラーとしては、「a+ce3は大文字A~Cではありません!」のようにしたいのです。
少し、プログラム文を作成しました。
また作成途中でコンパイルは出来ません。
#include<stdio.h>#include<ctype.h>#include<string.h>typedef struct in_data{ char a[1]; char b[2]; char c[3];} in_dataint main(int argc, char *argv[]){ FILE *fp; char str[400]; in_data ex; if((fp=fopen(argv[1],"r"))==NULL){ puts("ファイルが開けませんでした。
"); exit(-1); } else { while(fgets(str,sizeof(str),fp)!=NULL){ str[strlen(str)-1]='\\0'; for(i=0;str[i]!=NULL;i++){ switch(str[i]){ case 'A': memcpy(ex.a,str,sizeof(ex.a)); printf("a=%s\¥n",ex.a); break; case 'B': memcpy(ex.b,str,sizeof(ex.b)); printf("b=%s\¥n",ex.b); break; case 'C': memcpy(ex.c,str,3); break;

ベストアンサー

大前提。
typedef struct {char a[1];char b[2];char c[3];} in_dataこれじゃ要素数が全然足りない。
そもそもCの文字列は末尾に'\\0'が必要なのでchar a[1];じゃ1文字も入らない。
#include<stdio.h>#include<stdlib.h>#include<ctype.h>#include<string.h>typedef struct in_data{ char a[100]; char b[100]; char c[100];} in_data;int main(int argc, char *argv[]){ FILE *fp; char str[400]; in_data ex; int i, ac=0, bc=0, cc=0; memset(&ex, 0, sizeof ex); if((fp=fopen(argv[1],"r"))==NULL){ puts("ファイルが開けませんでした。
"); exit(-1); } while(fgets(str,sizeof(str),fp)!=NULL){ if (str[strlen(str)-1]=='\¥n')str[strlen(str)-1]=='\\0'; for(i=0;str[i]!=NULL;i++){ switch(str[i]){ case 'A': memcpy(&ex.a[ac],&str[i],1); ac++; //printf("a=%s\¥n",ex.a); break; case 'B': memcpy(&ex.b[bc],&str[i],1); bc++; //printf("b=%s\¥n",ex.b); break; case 'C': memcpy(&ex.c[cc],&str[i],1); cc++; break; } } } printf("a=%s\¥n",ex.a); printf("b=%s\¥n",ex.b); printf("c=%s\¥n",ex.c);}>文字列の末尾にNULLが入るからナル文字とNULLは違います。
ナル文字は'\\0'と書きます。
NULLとは空ポインタ定数(どこも指してないポインタ)のことです。
>Cには、ヌルを考慮しない(ヌルを削除?
)で格納できると…だったらprintf()で出力することをあきらめてください。
printf()の"%s"は、ナル文字で終端された文字列を前提にしてます。
(文字列を扱うライブラリ関数は全部そうです。
)それにしたって、だいたいchar a[1];char b[2];char c[3];って、最初からファイルがABBCCCであることを前提にしてますよね?
もしファイルがAAABBBBCCCCCだったらどうするんでしょうか?
(入力値が固定なら「入力」にする意味がない。
だいたい問題文にも>例として>ABBCCCとファイルに書かれていたらと書いてある。
「例として」と書いてある以上、これ以外の入力もありえるということ。