C言語で文字列変換プログラムの実装で手こずっています。同じ結果しか表示されず、謎の文字もついてしまいます。どこを修正すればいい?

このQ&Aのポイント
  • C言語で文字列変換プログラムを作成していますが、うまく実装できず困っています。実行結果が謎の文字と同じものしか表示されず、入力ファイルの内容も正しく読み込まれません。
  • プログラムの流れを考えたところ、特に(2)の部分で手こずっています。文字列を正しく配列に保存できず、謎の文字が表示される原因になっています。
  • 入力ファイルが2行以上ある場合、1行目の結果しか出力されない問題もあります。プログラム全体の修正が必要なようです。
回答を見る
  • ベストアンサー

文字列変換のプログラムについて

こんにちは。 C言語で以下のようなプログラムを作りたいと考えているのですが、うまく実装できず困っています。 入力ファイルには、【単語(ひらがな)+Tab+その読み(音素列)】が書かれているとします。 例: あいうえお(Tab)a i u e o かきくけこ(Tab)ka ki ku ke ko ・・・ (音素は半角空白で分けられているものとします) このファイルを読み込んで、【単語(ひらがな)+Tab+単語(カタカナ)+Tab+その読み(音素列)】を別のファイルに書き込む  例: あいうえお(Tab)アイウエオ(Tab)a i u e o かきくけこ(Tab)カキクケコ(Tab)ka ki ku ke ko ・・・ というプログラムを作りたいと考えています。 アルゴリズムとして、 (1) ファイルから1行読み込む (2) Tab文字がくるまでの文字列を配列に保存(例でいう「あいうえお」の部分です) (3) Tab文字の次の文字から行末までの文字列を配列に保存(例でいう「a i u e o」の部分です) (4) (2)の1文字ずつをカタカナに変換(ASCIIコードの変換で可能?) (5) (2)(3)(4)を用いて出力用ファイルに書きこむ という流れを考えたのですが、(2)の部分でまず手こずっています。 #include<stdio.h> main(){ FILE *fin; FILE *fout; char buff[200]; char word[200]; int i=0; /*読み込み用ファイルを開く*/ fin = fopen("input.txt", "r"); if( fin == NULL ){ printf( "File open error\n" ); return; } /*書き込み用ファイルを開く*/ fout = fopen("output.txt", "w"); if( fout == NULL ){ printf( "File open error\n" ); return; } /*1行ずつ読み込む*/ /*読み込める間繰り返す*/ while(fgets(buff,200,fin) != NULL){ /*タブ文字がくるまで拾う*/ while(buff[i] != '\t'){ /*文字列を配列wordに保存*/ word[i] = buff[i]; i++; } /*保存できているかの確認*/ printf("%s",word); fclose(fin); fclose(fout); } 実行後、wordの中身が表示されるのですが、 あいうえお,(文字化け)(文字化け) というように、【,(文字化け)(文字化け)】という謎の文字がついてしまいます。 また、入力ファイルの中身が2行以上でも、 あいうえお,(文字化け)(文字化け) あいうえお,(文字化け)(文字化け)・・・ というように、1行目の結果しか出てこないです。 どこを直せばいいのでしょうか? (というかそもそもCよりPerlとかで作ったほうがもっと楽なのかもしれないですが・・・) 教えて頂けると助かります。よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • chie65535
  • ベストアンサー率43% (8514/19356)
回答No.5

#include<stdio.h> void main(void){ FILE *fin; FILE *fout; char buff[200]; char *p1,*p2; /*読み込み用ファイルを開く*/ fin = fopen("input.txt", "rt"); if( fin == NULL ){ printf( "File open error\n" ); return; } /*書き込み用ファイルを開く*/ fout = fopen("output.txt", "wt"); if( fout == NULL ){ printf( "File open error\n" ); return; } /*1行ずつ読み込む*/ /*読み込める間繰り返す*/ while(fgets(buff,200,fin) != NULL){ for (p1=buff;*p1;p1++) if (*p1 == '\t') { *p1++ = '\0'; break; } /*保存できているかの確認*/ printf("%s\t",buff); fprintf(fout,"%s\t",buff); for (p2=buff;*p2;p2+=2) { *(short *)p2 = *(short *)p2 + 41217; if ((p2[1] < 0) || (p2[1] == 127)) p2[1]++; } printf("%s\t%s\n",buff,p1); fprintf(fout,"%s\t%s\n",buff,p1); } fclose(fin); fclose(fout); }

その他の回答 (8)

  • chie65535
  • ベストアンサー率43% (8514/19356)
回答No.9

>のところで、for文の終了条件がなぜ*p1となるのかが分かりません。(ポインタが苦手なもので・・・) C言語で「条件式において、非0は真、0は偽」です。 本当なら for (p1=buff;*p1 != '\0';p1++) { と書くべきですが、 条件式「*p1 != '\0'」は「0じゃないなら真、0なら偽」なので、条件式を「*p1」と書いても、結果は同じです。 > (結局if文でbreakするから何でもいいような気もしますが・・・) だめですよ。もしタブ文字が来なかったら、forループが終了しません。 文字列を「先頭から末尾までポインタでループする時」は、常套的に for (p1=buff;*p1;p1++) { と言う書き方をします。「決まり文句」みたいなモノです。 >また、 *p1++ = '\0'; について >>これはタブがあったら、タブの所に「文字列終端」を書き込んで「タブの次の位置をp1に覚える」と言う処理。 >と説明してくださっていますが、つまり、タブの部分に文字列終端(\0)を上書き→p1を次の位置(最初の音素)にする という処理を行っているということでしょうか? そうです。タブがあった場所に文字列終端を書き込んでから、p1を1つ進めています。 >2行目は文字コード分足してるのかな?と思うのですが、 > *(short *)p2 = *(short *)p2 + 41217; カタカナとひらがながの文字コードを「shortの数値」として扱った場合、両者の「数値の差」が「41217」なので、その分を足しています。 >3行目のif文と、 > if ((p2[1] < 0) || (p2[1] == 127)) p2[1]++; 差を足してカタカナにしたあと、シフトJISの文字コードの第2バイトが「127」か「負数」になった場合は、文字コードを1文字分「シフト(増加)」させる必要があります。 その「シフト(増加)分」を足しています。 これが「シフトJIS」が「シフトJIS」と呼ばれている所以(ゆえん)です。 >for文の繰り返し条件でなぜ+2するのかが分からないです。 >for (p2=buff;*p2;p2+=2) { シフトJISの漢字コードは「2バイトで1文字」なので、「1文字づつループする為」に「2バイトづつ進めている」のです。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.8

#6 の補足のところだけど.... for にしろ while にしろ, 与える条件は「終了条件」じゃなくて「継続条件」な. で, C の「条件」は「値が 0 なら偽, 0 でなければ真」だ. まあ, Perl なら use utf8; use Encode; while (<>) { $_ = Encode::decode(ファイルの文字コード, $_); chomp; my ($word, $phonic) = split /\t/; my $w = $word =~ tr/ひらがなたち/カタカナたち/r; print Encode::encode(文字コード, join("\t", $word, $w, $phonic)), "\n"; } くらい (スクリプトの文字コードは UTF-8) でいいと思うんだけど.

  • Wr5
  • ベストアンサー率53% (2177/4070)
回答No.7

>>printf("%d", '\t'); >>してみては? >結果「9」になりました。 >ASCIIの制御コードでしょうか・・・。 …タブのASCIIコードは9でしたな。 8だったのは…ゴミデータ?? >>した後のbuffの中身をダンプしてみて下さい。 >FFFFFF82FFFFFFA0FFFFFF82FFFFFFA2FFFFFF82FFFFFFA4FFFFFF82FFFFFFA6FFFFFF82FFFFFFA809 >61206920752065206F0000000048FFFFFFAA220000000000FFFFFFC0FFFFFFFF11FFFFFF8001000000 for(i=0;i<sizeof(buff);i++) printf("%02X ", (unsigned int)buff[i]); とすべきでしたか……。 >16進数の何かでしょうか・・・? 読み込んだ文字列のコードです。 Shift-JISですかね。 途中に00が出力されている場所が'\0'になります。 # それ以降のデータは「文字列」としては無視される。

sou-e9
質問者

補足

ありがとうございます。 ダンプした結果について >読み込んだ文字列のコードです。 >Shift-JISですかね。 > 途中に00が出力されている場所が'\0'になります。 ># それ以降のデータは「文字列」としては無視される。 buffとwordのダンプの結果を見ると、「あいうえお」は両方ちゃんと入っているみたいです。 ということは、wordの「お」(A8)から00までの間の 2CFFFFFFFDFFFFFFFE07 が文字化けの原因になっているということでしょうかね。 うーん、色々と謎です・・・。

  • chie65535
  • ベストアンサー率43% (8514/19356)
回答No.6

訂正と解説。 printf("%s\t%s\n",buff,p1); fprintf(fout,"%s\t%s\n",buff,p1); の2行は printf("%s\t%s",buff,p1); fprintf(fout,"%s\t%s",buff,p1); に変更して下さい。 for (p1=buff;*p1;p1++) if (*p1 == '\t') { *p1++ = '\0'; break; } これはタブがあったら、タブの所に「文字列終端」を書き込んで「タブの次の位置をp1に覚える」と言う処理。 こうすると printf("%s\t",buff); fprintf(fout,"%s\t",buff); で「あいうえお<タブ>」を出力できる。 buffは あいうえお + EOS + a i u e o + 改行 + EOS になっていて、p1は「a」の位置を示している。 for (p2=buff;*p2;p2+=2) { *(short *)p2 = *(short *)p2 + 41217; if ((p2[1] < 0) || (p2[1] == 127)) p2[1]++; } は「ひらがなをカタカナに直に変換」している(文字コードは「シフトJIS」を想定している) 元のひらがなは、既にprintf、fprintfで出力済みなので「ひらがなを直接書き換えてカタカナにしてしまう」事が可能なのだ。 その後で printf("%s\t%s",buff,p1); fprintf(fout,"%s\t%s",buff,p1); により「カタカナ<タブ>音素列<改行>」を出力している(p1の末尾には改行が入っているので、明示的な改行はしない) その結果、 あいうえお a i u e o かきくけこ ka ki ku ke ko さしすせそ sa si su se so たちつてと ta ti tu te to なにぬねの na ni nu ne no はひふへほ ha hi hu he ho まみむめも ma mi mu me mo やゆよ ya yu yo わをん wa wo n の入力が あいうえお アイウエオ a i u e o かきくけこ カキクケコ ka ki ku ke ko さしすせそ サシスセソ sa si su se so たちつてと タチツテト ta ti tu te to なにぬねの ナニヌネノ na ni nu ne no はひふへほ ハヒフヘホ ha hi hu he ho まみむめも マミムメモ ma mi mu me mo やゆよ ヤユヨ ya yu yo わをん ワヲン wa wo n となります。

sou-e9
質問者

補足

回答ありがとうございます。 プログラムまで作っていただき、申し訳ないです。 ポインタを使ってやるということは考えても無かったです・・・。 作っていただいたプログラムを読ませていただいたのですが、良く分からない所があるので、お時間があるときで構わないので教えていただきたいです。 (1) for (p1=buff;*p1;p1++) if (*p1 == '\t') { *p1++ = '\0'; break; } のところで、for文の終了条件がなぜ*p1となるのかが分かりません。(ポインタが苦手なもので・・・) *p1ということはbuffで保持している文字列のどれかであると思うのですが、なぜ*p1だけでいいのかが分からないです。 (結局if文でbreakするから何でもいいような気もしますが・・・) また、 *p1++ = '\0'; について >これはタブがあったら、タブの所に「文字列終端」を書き込んで「タブの次の位置をp1に覚える」と言う処理。 と説明してくださっていますが、つまり、タブの部分に文字列終端(\0)を上書き→p1を次の位置(最初の音素)にする という処理を行っているということでしょうか? (2)ひらがなからカタカナへの変換部分 for (p2=buff;*p2;p2+=2) { *(short *)p2 = *(short *)p2 + 41217; if ((p2[1] < 0) || (p2[1] == 127)) p2[1]++; } を詳しく説明していただきたいです。 2行目は文字コード分足してるのかな?と思うのですが、3行目のif文と、for文の繰り返し条件でなぜ+2するのかが分からないです。 長々となってしまい申し訳ないです。 どうぞよろしくお願いします。

  • Wr5
  • ベストアンサー率53% (2177/4070)
回答No.4

>この「8」が意味していることはいったい何なのでしょうか・・・。 printf("%d", '\t'); してみては?

sou-e9
質問者

補足

ありがとうございます。 >printf("%d", '\t'); >してみては? 結果「9」になりました。 ASCIIの制御コードでしょうか・・・。

  • Wr5
  • ベストアンサー率53% (2177/4070)
回答No.3

アクセス違反でふっとんでもいいコード…ですかねぇ。 >てことはもしや取り出した1行は >あいうえお(文字列)+$0+Tab+a i u e o(文字列)+$0+(文末) >という構成になっているのでしょうか? fgets(buff,200,fin) した後のbuffの中身をダンプしてみて下さい。 for(i=0;i<sizeof(buff);i++) printf("%02X ", buff[i]); みたいな感じで。 で…… >/*保存できているかの確認*/ >printf("%s",word); の時点で'\0'で終端しているか確認して下さい。 # ダンプについては上記のような処理で。 >/*タブ文字がくるまで拾う*/ が開始される時点でのiの値にも注意…でしょうね。 で…… {と}の対応が取れていますか? # 現状掲示されているコードだと、1行目読み込んだ後ファイルクローズしています。 # ので、その次の読み込みで吹っ飛びかねませんが。 # というかmain()閉じていないからコンパイルできない。

sou-e9
質問者

補足

ありがとうございます。 >fgets(buff,200,fin) >した後のbuffの中身をダンプしてみて下さい。 FFFFFF82FFFFFFA0FFFFFF82FFFFFFA2FFFFFF82FFFFFFA4FFFFFF82FFFFFFA6FFFFFF82FFFFFFA809 61206920752065206F0000000048FFFFFFAA220000000000FFFFFFC0FFFFFFFF11FFFFFF8001000000 0300000000000000FFFFFFC0FFFFFFFF11FFFFFF800000000040FFFFFFD4220000000000FFFFFFE0FF FFFFC42BFFFFFF800100000078FFFFFFAA220000000000702717FFFFFF800100000001000000726F77 00702717FFFFFF8001000000502317FFFFFF800100000000FFFFFFCE220000000000FFFFFFC0FFFFFF C42BFFFFFF800100000041534349490000002A2116FFFFFF80010000000000000000000000FFFFFFFE FFFFFFA106FFFFFF800100000000FFFFFFCE22000000000030FFFFFFAB22000000000068072EFFFFFF 8001000000FFFFFFF0FFFFFFCC220000000000FFFFFF90FFFFFFAB220000000000 となりました。 16進数の何かでしょうか・・・? また、タブ文字までをwordに保存して、その後wordの中身を上と同様にダンプすると FFFFFF82FFFFFFA0FFFFFF82FFFFFFA2FFFFFF82FFFFFFA4FFFFFF82FFFFFFA6FFFFFF82FFFFFFA82C FFFFFFFDFFFFFFFE0700000000000000000000000000000000000070FFFFFFAA220000000000FFFFFF F3FFFFFF9E0BFFFFFF800100000050FFFFFFAA22000000000004FFFFFFE024FFFFFF80010000000200 0000000000000100000000000000FFFFFFA0FFFFFFAA2200000000000000000000000000FFFFFF80FF FFFFAA22000000000004FFFFFFE024FFFFFF800100000000FFFFFFAA2200000000000B0D07FFFFFF80 0100000060FFFFFF9F1CFFFFFF80010000000E6019FFFFFF8001000000FFFFFF86FFFFFFAA22000000 0000616D16FFFFFF800100000070FFFFFFAA220000000000FFFFFFBC1B16FFFFFF8001000000702717 FFFFFF8001000000FFFFFF80FFFFFFAA2200000000000100000001000000 となりました。 >で…… >{と}の対応が取れていますか? すみません、}が1つ足りなかったです。

  • akubi_m
  • ベストアンサー率22% (12/54)
回答No.2

fgets()する前のbufとword[i] = buff[i];する前のwordをprintf()してみてください。 何か分かりませんか?

sou-e9
質問者

補足

ありがとうございます。 printfすると、buffのほうは文字化けでちょっとよくわからなかったのですが、wordのほうは8になりました。 この「8」が意味していることはいったい何なのでしょうか・・・。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

C の「お約束」です: 「文字列」の最後には, 何がありますか? もちろん最後に書かれているように Perl などで作る方が「はるかに」楽.

sou-e9
質問者

お礼

すみません。$0でなく\0です。

sou-e9
質問者

補足

ありがとうございます。 文字列の最後はnull文字($0)がつくんですよね。 てことはもしや取り出した1行は あいうえお(文字列)+$0+Tab+a i u e o(文字列)+$0+(文末) という構成になっているのでしょうか? やはりPerlのほうが楽ですよね・・・。 Perlで作ることも考えていこうと思います。

関連するQ&A

  • 文字列入れ替えのプログラムについて

    こんばんは。 文字列入れ替えのプログラムを作っているのですが、分からない部分があるので教えて頂きたいです。 入力ファイルには、 AAAAAAA(必ず7文字)【半角スペース】B(文字数はバラバラ)【tab】C(文字数はバラバラ) というデータが複数入っているものとします。 このファイルを読み込んで、 B【tab】C;;;(セミコロン3つ)AAAAAAA という順に並べ替えるプログラムを作成したいと考えています。 アルゴリズムとしては、 (1)ファイルから1行読み込む (2)読み込んだ行のうち最初の7文字を配列に保存 (3)半角スペースを除き、それ以降(B【tab】C)を出力ファイルに書き込む (4)(2)で保存したものに;;;をつけ、(3)の後ろに書き込む というのを考えていますが、(3)の工程をどうすればいいか分からず困っています。 (改行(\n)までをファイルに書き込めばいいと思うのですが、プログラムでどう書けばいいかが分かりません) よろしくお願いします。 #include<stdio.h> void main(void){ FILE *fin; FILE *fout; char buff[200]; char *p1; char word[200]; int i=0; /*読み込み用ファイルを開く*/ fin = fopen("input.txt", "rt"); if( fin == NULL ){ printf( "File open error1\n" ); return; } /*書き込み用ファイルを開く*/ fout = fopen("output.txt", "wt"); if( fout == NULL ){ printf( "File open error2\n" ); return; } /*1行ずつ読み込む*/ /*読み込める間繰り返す*/ while(fgets(buff,200,fin) != NULL){ i=0; /* buffの先頭アドレスをp1に与える*/ p1=buff; /*工程2:最初から7文字分を配列wordに保存*/ for (i=0;i<7;i++){ word[i]=*p1; *p1++; } /*半角スペース部分をとばし、p1をBの最初の文字にする*/ *p1++;      ここで工程3を行う     /*工程4:保存しておいた文字列を書き込む*/ fprintf(fout,";;;%s\n",word); } fclose(fin); fclose(fout); }

  • ファイルの英字を全部小文字に変換して新規テキストに出力

    テキストファイルの英字を全部小文字に変換して新規テキストに出力するプログラムをつくりましたがうまくいきません。なにがいけないですか? #include <stdio.h> #include <stdlib.h> #include <ctype.h> #define STR_MAX 256 int main(void) { FILE *fi, *fo; /* ファイルポインタ用 */ char fin[100], fout[100]; /* ファイル名用 */ char buff[STR_MAX], *q; /* 文字列用 */ printf("入力ファイル名 : "); /* プロンプト表示 */ gets(fin); /* ファイル名入力 */ printf("出力ファイル名 : "); /* プロンプト表示 */ gets(fout); /* ファイル名入力 */ q = buff;   /* 入力ファイルオープン */ if((fi = fopen(fin, "r")) == NULL){ printf("入力ファイルがオープンできません\n"); exit(1); /* 強制終了 */ }   /* 出力ファイルオープン */ if((fo = fopen(fout, "w")) == NULL){ printf("出力ファイルがオープンできません\n"); exit(1); /* 強制終了 */ } while(fgets(buff, STR_MAX, fi) != NULL){ /* 1行読み込み */ *q = tolower(*q); ++q; fprintf(fo, "%s", buff); /* 1行出力 */ } fclose(fi); /* 入力ファイルクローズ */ fclose(fo); /* 出力ファイルクローズ */ return(0); }

  • ファイルの入出力を行っての文字列反転

    入力した文字列を反転させて出力したいのですが どうしたらよいでしょうか? #include <stdio.h> #include <stdlib.h> #include <string.h> /* 定数 */ #define DELIMITER "/ ," /* 区切り文字 */ int main(void) { FILE *fin,*fout; char infile[40],outfile[40],s[256],s2[256]; char *token; char *strch[50]; int count = 0; int i; printf("入力ファイル名="); gets(infile); printf("出力ファイル名="); gets(outfile); if( (fin=fopen(infile,"r"))==NULL) { /* 入力ファイルオープン */ printf("入力ファイルがオープンできません\n"); exit(EXIT_FAILURE); } if( (fout=fopen(outfile,"w"))==NULL) { /* 出力ファイルオープン */ printf("出力ファイルがオープンできません\n"); exit(EXIT_FAILURE); } while(fgets(s,256,fin)!=NULL) { /* 入力ファイルから読み込んだデータを */ token = strtok(s, DELIMITER); while (token != NULL) { strch[count] = token; token = strtok(NULL, DELIMITER); count++; } for(i = count; i > 0; i--) { strcat(s2, strch[i]); } fputs(s2,fout); /* 出力ファイルに書き込み */ } fclose(fin); /* 入力ファイルクローズ */ fclose(fout); /* 出力ファイルクローズ */ return 0; }

  • ファイルの入出力を行って文字を変換する

    入力するファイルにa~zを記入しておき、 出力するファイルにaなら1、bなら2、zなら26に変換させたいのですがどうしたらよいでしょうか? #include <stdio.h> #include <string.h> #define DELIMITER "/ ," /* 区切り文字 */ int main(void) { FILE *fin,*fout; int count=0; int i; char s[256], s2[256]; char alpha[]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'}; int kazu[]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26}; char *taken; char *strch[50]; if( (fin=fopen("file1.txt","r"))==NULL) { printf("入力ファイルがオープンできません\n"); exit(EXIT_FAILURE); } if( (fout=fopen("file2.txt","w"))==NULL) { printf("出力ファイルがオープンできません\n"); exit(EXIT_FAILURE); } while(fgets(s,256,fin)!=NULL) { while (token != NULL) { strch[count]=token; token = strtok(NULL, DELIMITER); count++; } memset(s2, NULL, sizeof(s2)); fprintf(fout,"%d\n",s2); } fclose(fin); fclose(fout); return 0; }

  • 文字列入力について

    いつも大変お世話になってます。 文字列の扱いがどうも苦手なようなのでまた教えていただきに参りました。 今回は文字列の最大長を指定せずに入力時に幾らでも書けるプログラムを書きたいと思ってます。 int main() { ↓★最大長を指定しない char* buff=""; //初期化 printf("文字列入力\n"); if(gets_s(buff,sizeof(buff)-1) == NULL){ printf("NULL\n"); } ~~~~別処理~~~~ printf("%s\n", buff); return 0; } 文字列を入力したところで別処理に入る前にエラーが出て強制終了します。 aaa.exe の 0x10259554 でハンドルされていない例外が発生しました: 0xC0000005: 場所 0x00415986 に書き込み中にアクセス違反が発生しました。 こういったエラーはポインタの扱い方に誤りがあるのでしょうか? また、最終的に文字列の最大長を指定せずに宣言し、入力できるように するにはどのようにしたらよろしいのでしょうか?

  • ファイル入出力で

    現在ファイル入出力の項目をしているのですが、以下の内容で実行すると エラーが出てどうしても実行できません。主にどこを直せばいいのでしょうか? /* ファイルをコピーするプログラム */ #include <stdio.h> int main(void) { FILE *fin, *fout; char infile[40], outfile[40]; char str[256]; printf("コピー元ファイル = "); scanf("%39s", infile); printf("コピー先ファイル = "); scanf("%39s", outfile); if( (fin = fopen(infile, "r") ) == NULL) { printf("Input file open error.\n"); return 1; } if( (fout = fopen(outfile, "w") ) == NULL) { printf("Output file open error.\n"); fclose(fin); return 1; } while(fgets(str, sizeof(str), fin) != NULL) { fputs(str, fout); } fclose(fin); fclose(fout); return 0; } エラーは FILE 、fin, fout,NULLの未定義です。 よろしくお願いします。

  • 配列の比較について・・・困ってます・・。

    ご質問させていただきます。 これは、fin2というファイルから数値を抜き出し配列に格納して、finの文字列と比較し、その文字列のある場所で配列の数値と比較し、合致したら、ある出力をするというものなんですが、 配列に格納した数値が、 a[1]=[123] b=[234] a[1]=[345] b=[400] というふうに増えていくときは問題ないですが、途中でたとえば a[n]=100 b[n]=400 a[n+1]=300 b[n+1]=358 という風にn+1番目のaより、n番目のbが大きいときに、止まってしまうんです、これをうまく処理して最後まで比較させたいんですが、どうしてもうまくいきません。どなたかたすけてください。やはり、 n==b[yabu]の処理の後になんか書けばいいんでしょうか?長々と申し訳ございませんでした。 if(fin2!=NULL) { int yabu=0; for(int i=0; fgets(c,CHARMAX,fin2)!=NULL;i++) { sscanf(c,"%d%*c%*c%d",&a[yabu],&b[yabu]); fprintf(fout2,"%d::::::::::::::%d:%d\n",yabu,a[yabu],b[yabu]); yabu++; } } int yabu=0; n=0; while(fgetc(fin)!=EOF) { n++; if(n==a[yabu]) { fprintf(fout2,"A "); } else if(n==b[yabu]) { fprintf(fout2,"B "); yabu++;} else {fprintf(fout2,"C "); } } printf("%d\n",yabu);

  • 文字列操作(分割)のプログラムについて!

    ファイルのデータを1行ずつ読み込み、","で区切られた要素に分割して配列に格納するプログラムの作り方を教えてください。 下記のようなファイルがあり、各行の3つめの要素の数字(ハイフンを含む)を各行で比較し、昇順に行をソートするというプログラムを作成しております。 要素数は4つめ以降各行ばらばらです。 [ファイル test.txt] 2013/08/01,16:19,20130801161906-210164001071,,,川口,神奈川,,電話番号 2013/08/01,11:32,20130802003256-116091178056,鈴木,埼玉,mail,電話番号 2013/08/01,15:55,20130801155519-119072194140,,,山田,東京,mail まず、ファイルを読み込み、3つめの要素を下記のように配列s[i]に格納しようとしたのですが、うまく配列に3つめの要素がはいってくれません。 配列の格納にstrcpyを用いたところ、途中でプログラムが強制終了し、配列への格納ができませんでした。 この原因と対策がわからなくて困っております。 [格納の例] s[0]=20130801161906-210164001071 s[1]=20130802003256-116091178056 s[2]=20130801155519-119072194140 [自分のプログラム] #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX 300 int main() { char filename[] = "test.txt"; FILE *fp; char data[MAX], *words[MAX],*s[MAX],*cp; const char *delim=","; int g,i=0,j,len; // ファイル・オープン if ((fp = fopen(filename, "r")) == NULL) { printf("ファイルのオープンに失敗\n"); exit(1); } while (fgets(data, MAX, fp) != NULL) //1行読み込む { cp = data; for (len = 0; len < MAX; len++) { if ((words[len] = strtok(cp, delim)) == NULL) //","で文字列を分割 break; cp = NULL; } s[i] = words[2]; //3つ目の要素を配列に格納 i++; } for(j=0;j<3;j++){ //表示 printf("%s\n",s[j]); } [実行結果] 20130801155519-119072194140 20130801155519-119072194140 20130801155519-119072194140 プログラムの訂正箇所,上記と異なるプログラム,大体の流れ… などなんでもかまいませんので、教えていただきたいです。よろしくお願いします。

  • C言語の問題

    選んだファイルのデータを読み取り、そのファイルのデータの中の文字列を数えるプログラム(例えば、「I like sport」 だったら3ワード)を作りたいのですが、文字数を数えるものしかわからないです。 一応、下のプログラムが文字数を数えるものですが、どうすれば文字列を数えるものになりますでしょうか?教えてください。 #include <stdio.h> #include <string.h> #include <stdlib.h> main() { FILE *fin; char filename[20]; char data[256]; int n; printf("ファイル名の入力 :"); gets(filename); fin=fopen(filename,"r"); if(fin == NULL){ printf("%sがオープンできません!\n",filename); exit(1); } while(fgets(data,256,fin) !=NULL){ } n=strlen(data); printf("ファイル %s には、%dワードがあります。\n",filename,n); fclose(fin); }

  • C言語 文字列格納

    テキストファイルから整数データ又は文字列を読み込んで配列に格納する動作についての質問です。 テキストファイルが1行区切りの整数型なら1次元配列で for(i = 0; i < maxSize; i++) { fscanf(fp,"%d", &data[i]); } テキストファイルが1行区切りの文字列なら2次元配列で for(i = 0; i < MAXSIZE; i++) { if (fscanf(fp,"%s", &data[i][300]) == EOF) break; } for(j = 0; j < i; j++) printf("%s\n", data[j]); みたいな具合に格納できたんですが、 テキストファイルが1行区切りのデータではなく、空白文字区切りの文字データだった場合、それぞれどのようにして配列に格納すればいいかがわかりません。 イメージとしては、1文字目から見ていって空白が出ればそこで切って格納していくというかんじなのですが・・・ 質問の内容がわかりにくいかもしれませんが、是非教えてください。お願いします。

専門家に質問してみよう