• 締切済み

[C++]ファイル出力について

教えてください。 コマンドプロンプトから何行か書いた文章をファイルにしたいのですが、 うまくいきません。 作ったものの結果は1行1文字で出力されて、eofでうまく 終わってくれません。 コマンドプロンプトで入力(改行)された通りにファイルに出力 できるようにしたいので、どこがおかしいのか指摘お願いします。 #include <iostream> #include <fstream> #include <stdlib.h> #include <string.h> #include <string> using namespace std; int main(int argc, char *argv[]) { char str[100]; int i; i = 0; if (argc <= 1) { cerr << "Need filename" << endl; exit (1); } ifstream ifs(argv[1], ios::in); if (ifs) { cerr << "Caution" << argv[1] << " already exists " << endl; cerr << " Specify a different filename " << endl; exit (2); } ofstream ofs(argv[1], ios::out); if (!ofs) { cerr << " Unable to write to " << argv[1] << endl; exit (3); } while(str[i] !=EOF) { cin >> str[i]; ofs << str[i] << endl; i++; } return 0; }

みんなの回答

  • Werner
  • ベストアンサー率53% (395/735)
回答No.2

> while(str[i] !=EOF) > { >   cin >> str[i]; >   ofs << str[i] << endl; >   i++; > } str[i]はchar型なので、 cinからchar型に入力している事になり1文字ずつ入力されています。 (当然出力も1文字ずつ。) また、char型とEOFという値をもてないので、 EOFと比較してもいつ終わるかは運次第です。 他に、iが100以上になったときの対策が全くありません。 1行ずつ処理するなら例えば以下のような感じ。  string str;  while(!cin.eof())  {    getline(cin, str);    fs << str;  }

star323
質問者

お礼

回答ありがとうございます。 char型は符号なし数として扱われる0~255の値をとるので EOFの値である-1を判別できないということですか? char型ではなくて、文字列型を使えばよかったんですね。 明日実行してみます。

star323
質問者

補足

やってみたのですが、エラーはでずファイルも作られるのですが コマンドプロンプトのほうで入力したものが出力されませんでした。 もうちょっと考えてみます。 ありがとうございました。

回答No.1

cin >> str[i]; これだと空白文字を区切りとします。 getline に取り替えてみてください。

star323
質問者

お礼

回答ありがとうございます。 getlineで1行読み込みするということですね。 わかりました。 こんな簡単なことにありがとうございました。

関連するQ&A

  • C++のifstreamの使い方

    C++のifstreamの使い方で分からない所があるので、分かる方御教示ください。 下記は、C++で読み込んだファイルの中身が空だった場合を無理やり例外処理を使って書いてみたのですが、中身が存在する場合、たとえば、 line1 line2 line3 ではline1を無限に繰り返してしまいます。(1)を ifstream instream = inStream(argv[1]); while (instream >> input) にするとうまくいくようなのですが、この違いがよくわかりません。 違いを教えてください。 #include <iostream> #include <string> #include <fstream> using namespace std; ifstream inStream(char *str); int main(int argc, char *argv[]) { if (argc < 2) cout << "ファイル名を指定してください" << endl; else { try { string input; while (inStream(argv[1]) >> input) // (1) cout << input << endl; } catch (int i) { cerr << argv[1] << "を開けません" << endl; } } return 0; } ifstream inStream(char *str) { ifstream inStream(str); if (!inStream) throw 1; return inStream; }

  • ファイルの出力

    コマンドラインで指定したファイルの内容を一行ずつ表示するプログラムです。一行表示するごとに次の行も表示するか尋ねます。 #include<stdio.h> #include<stdlib.h> #include<ctype.h> int main(int argc, char *argv[]) {  FILE *fp;  char str[80];  char ch;  if (argc != 2){   printf("コマンドライン引数が違います\n");   exit(1);  }  if ((fp = fopen(argv[1],"r")) == NULL){   printf("ファイルが開けません");   exit(1);  }  while(!feof(fp)){   fgets(str, 79, fp);   if (!feof(fp)) printf("%s",str);   printf("追加しますか?(y/n)");   gets(str);   if ( toupper(*str) == 'N') break;   printf("\n");  }     if (fclose(fp) == EOF){   printf("ファイルを閉じれません\n");   exit(1);  }  return 0; } while文の   gets(str);  if ( toupper(*str) == 'N') break; この部分を  ch = getchar();  if ( toupper(ch) == 'N') break; でやると上手く実行できないのですが、なぜでずか?

  • ofstream::getがおかしい!

    ofstream::getの動作がおかしいのです #include <string> #include <iostream> #include <fstream> using namespace std; void main(void) { ifstream ifs; ofstream ofs; string str; char c; str="abc"; cout<<"before str: "<<str<<endl<<endl; ofs.open("gomi");ofs<<str;ofs.close(); ifs.open("gomi");for(str="";ifs.eof()==0;str+=c)ifs.get(c);ifs.close(); cout<<"after str: "<<str<<endl<<endl; } の結果が before str: abc after str: abcc になります 最後のcは何でつくのでしょうか? 回避する方法を教えてください

  • プログラムの説明

    C++の初心者です。 ↓のプログラムの動作はさっぱりわかりませんが、それについての説明は具体的に教えていただきたいです。(できれば、詳しく) #include <iostream> #include <string> int getNinzu(int ARGC, char *ARGV[]) throw (char const *){ if(ARGC!=2){ throw "Needs only one argument."; } int ninzu=std::atoi(ARGV[1]); if(ninzu<=0){ throw "Value is too small."; } return ninzu; } #include <cstdlib> #include <ctime> int randfive(){ static bool firsttime=true; if(firsttime){ firsttime=false; std::srand(std::time(NULL)); } return static_cast<int>(static_cast<double>(std::rand())/RAND_MAX*(5+1)); } #include <iomanip> int main(int ARGC, char* ARGV[]){ std::string cmdname=ARGV[0]; int ninzu; try{ ninzu=getNinzu(ARGC,ARGV); std::cout << std::setfill('0'); for (int i = 1; i <= ninzu; ++i) { int score = 0; for (int k = 0; k < 20; ++k) score += randfive(); std::cout << "C" << std::setw(5) << i << " " << score << '\n'; } }catch(char const *str){ std::cerr << str << std::endl << "Usage: " << cmdname << " ninzu" << std::endl; return 1; } }

  • プログラムの動作の仕方

    この下のプログラムは、WRITE <ファイル名>をコマンド行で入力すると、動作するプログラムなのですが、この通りにWRITE <test>としてもできません。 やり方を教えてください. #include <iostream> #include <fstream> using namespace std; int main(int argc,char *argv[]) { if(argc!=2){ cout << "使い方:WRITE<ファイル名>" << endl; return 1; } ofstream out(argv[1]); //出力ファイル if(!out){ cout << "出力ファイルが開けません" << endl; return 1; } char str[80]; cout << "文字列をディスクに書き込み、$で停止します" << endl; do{ cout << ": "; cin >> str; out << str << endl; }while(*str!='$'); out.close(); return 0; } お願いします。

  • C言語のシェルプログラミングの課題が分かりません。

    C言語のシェルプログラミングを作れという課題で、以下のように作ったんですが、実行して何度かコマンドを入力した後、exitによって一発で終わらせることができません。どのように書き換えればいいか教えて下さい。 また、他にも書き換えた方がよいと思えるところがあったら是非教えて下さいm(_ _)m #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/wait.h> #include <sys/types.h> #include MAX_ARGS 10 #include MAX_LEN 100 extern char **environ; void child(int argc, char *argv[MAX_ARGS]); int main(void){ int argc, n = 0; int status; char input[MAX_LEN], *argv[MAX_ARGS], *cp; const char *delim = "\t\n"; while (1){ ++n; printf("$ "); fflush(stdout); if(fgets(input, sizeof(input), stdin) == NULL){ break; } cp = input; for(argc = 0; argc < MAX_ARGS; argc++){ if((argv[argc] = strtok(cp, delim)) == NULL) break; cp = NULL; } if(strcmp(argv[0], "exit") == 0){ exit(0); } pid_t pid = fork(); if(pid == -1){ perror("fork"); exit(1); }else if(pid == 0){ child(argc, argv); }else{ wait(&status); } } return 0; } void child(int argc, char *argv[MAX_ARGS]{ execvp(argv[0], argv); }

  • C言語 シンプルソート

    C言語始めて1年の初心者です。 #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAXSIZE 10000 void swapData(char *x, char *y); void simpleSort(char data[], int first, int last); int main(int argc, char *argv[]) { int data[MAXSIZE][300]; int i, j, count; FILE *fp; if(argc != 2) { fprintf(stderr, "Usage: %s <filename>\n", argv[0]); exit(0); } if ((fp = fopen(argv[1], "r")) == NULL) { fprintf(stderr, "File %s is not found.\n", argv[1]); exit(0); } for(i = 0; i < MAXSIZE; i++) { if (fscanf(fp,"%s", &data[i]) == EOF) break; } simpleSort(data[], 0, i - 1); for(j = 0; j < i; j++) printf("%s\n", data[j]); } void swapData(char *x, char *y){ char tmp[300]; strcpy(tmp, x); strcpy(x, y); strcpy(y, tmp); } void simpleSort(char data[], int first, int last) { int i, j; for(i = first; i < last; i++){ for(j = i+1; j <= last; j++){ if(strcmp(&data[i], &data[j]) > 0) swapData(&data[i], &data[j]); } } } 読み込んだ文字データをシンプルソートするプログラムなんですが、コンパイルできません。 simpleSortの部分がおかしいみたいなんですが、見直しても先入観からか間違いを見つけられません・・・・ どなたか間違いを指摘していただけたら助かります。

  • C言語、ファイル操作、fgets()について

    次のプログラムは入力された行を読み込み、コマンドラインで指定されたファイルに書き込みます。 空白行が入力されたら、入力の終了とみなしてファイルを閉じます。続いてファイルを入力用に開き、 fgets()を使ってファイルの内容を表示するものです。 (ソースコードが長くてすみません) #include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char *argv[]) { FILE *fp; char str[80]; /* コマンドライン引数を検査する */ if(argc!=2) { printf("ファイル名を指定してください\n"); exit(1); } /* 出力用にファイルを開く */ if((fp = fopen(argv[1], "w"))==NULL) { printf("ファイルを開くことができません\n"); exit(1); } printf("終了するには空白行を入力してください\n"); do { printf(": "); gets(str); strcat(str, "\n"); /* 改行を追加する */ if(*str != '\n') fputs(str, fp); } while(*str != '\n'); fclose(fp); /* 入力用にファイルを開く */ if((fp = fopen(argv[1], "r"))==NULL) { printf("ファイルを開くことができません\n"); exit(1); } /* ファイルを読み込み直す */ do { fgets(str, 79, fp); if(!feof(fp)) printf(str); } while(!feof(fp)); fclose(fp); return 0; } 【質問】fgets()内のint型の数値「79」がどうして79なのかが分かりません。     80でも良いような気がするのですが・・・

  • C言語の質問です

    下記のプログラムはテキストファイルを読み込み、AからZまでの文字(小文字、大文字は区別しない)がそれぞれ何回 現れたかを数えるプログラムです。 #include <stdio.h> #include <stdlib.h> #include <ctype.h> int count[26]; int main(int argc, char *argv[]) { FILE *fp; char ch; int i; /* ファイル名の指定を調べる */ if(argc!=2) { printf("ファイル名の指定がありません\n"); exit(1); } if((fp = fopen(argv[1], "r"))==NULL) { printf("ファイルを開くことができません\n"); exit(1); } while((ch=fgetc(fp))!=EOF) { ch = toupper(ch); if(ch>='A' && ch<='Z') count[ch-'A']++; } for(i=0; i<26; i++) printf("%c は %d 回出現\n", i+'A', count[i]); fclose(fp); return 0; } 1)int count[26]; で、なぜ26なのかが分かりません。 2)count[ch-'A']++; はどういう動作をするのか詳しく教えてほしいです。 3)よって、for文がどういう動作で表示しているのかが分かりません。 未熟者の私ですが、どなたか教えていただけないでしょうか?

  • c言語でデータの指定列の度数分布をつくろうとしています。

    c言語でデータの指定列の度数分布をつくろうとしています。 以下のように1列のデータに対してはプログラムを組むことができます。 #include<stdio.h> #include<stdlib.h> #define UPPERBOUND 2.0 #define LOWERBOUND -2.0 #define RANGE 0.1 int main(int argc, char* argv[]){ int i; FILE *fp; FILE *fp2; char str[256]; if(argc != 2 && argc != 3){ printf("***usage: %s <datafilename>\n", argv[0]); exit(-1); } if((fp = fopen(argv[1], "r")) == NULL){ printf("can't open file\n"); exit(-1); } if(argc == 3){ if((fp2 = fopen(argv[2], "w")) == NULL){ printf("can't open outputfile\n"); exit(-1); } } int tablesize = (UPPERBOUND-LOWERBOUND)/RANGE; int table[tablesize]; for(i=0; i<tablesize; i++){ table[i] = 0; } while((fgets(str, 256, fp)) != NULL){ double dbl = atof(str); if(!(dbl < LOWERBOUND || dbl > UPPERBOUND)){ int n = (dbl-LOWERBOUND)/RANGE; table[n]++; } } for(i=0; i<tablesize; i++){ printf("%lf~%lf\t: %d\n", LOWERBOUND+(i*RANGE), LOWERBOUND+((i+1)*RANGE), table[i]); if(argc == 3){ fprintf(fp2, "%lf~%lf\t: %d\n", LOWERBOUND+(i*RANGE), LOWERBOUND+((i+1)*RANGE), table[i]); } } return 0; } そこで複数列のデータに対して、例えば10列100行のデータに対して6列目だけを見たいときはどうすればできますでしょうか?

専門家に質問してみよう