ページ 1 / 1
指定した行に値を書き込む関数
Posted: 2010年6月07日(月) 12:04
by シオン
指定した行に値を書き込む関数を作っております
DXライブラリを使っております。
// 第一引数 書き込む行、第二以降 書き込む文字列
FileDataSave(int index, ???? );
// ~処理~
num = 3;
FileDataSave( 1, "あああ%d", num);
とするとtest.txtの1行目に
"あああ3"と保存する関数を作りたいです。
ファイルに書き込む処理だけならかけるのですが・・・。
FILE *fp;
fp = fopen( "MapData.txt", "w");
fprintf( fp, "書き込みたい文字列 ");
fclose(fp);
Re:指定した行に値を書き込む関数
Posted: 2010年6月07日(月) 12:54
by たいちう
> とするとtest.txtの1行目に
> "あああ3"と保存する関数を作りたいです。
ファイルを先頭から最後まで全て新しく書き直すのが一番簡単です。
http://www.kouno.jp/home/c_faq/c19.html#0
Re:指定した行に値を書き込む関数
Posted: 2010年6月07日(月) 15:02
by 通りすがり
fopenには様々なモードがあります
ちなみにwの場合は書き込み専用で
指定した名前のファイルがない場合には自動で作成し
既に存在した場合にもそのファイルの内容を全て破棄して
新しく上から書き込むモードです
書き込みたいファイルを一旦読み込んでその中身を保持しておき
新たに書き込みたい内容と保持しておいた内容を続けて書き込めば
1行目に付け足した形になると思います
たとえばファイルの中身が
かきくけこ
さしすせそ
たちつてと
だったとして
1行目にあいうえおを書き込みたい場合
かきくけこ
さしすせそ
たちつてとを一旦保存しておき
あいうえおを書き込んだ後
かきくけこ
さしすせそ
たちつてとを書き込みます
あとはコード化してみましょう
※ちなみに1行目ではなく最後の行に足したいのであれば
fopenのモードをaにすることで達成できます
Re:指定した行に値を書き込む関数
Posted: 2010年6月07日(月) 20:20
by シオン
アドバイスありがとうございます。
書き込む行にすでに文字列があった場合
行をずらすのではなく置きかえる仕様にしたいです。
文字列を読み込み特定の行のみの物を変更すると言ったことがわかりません・・・。
教えては頂けないでしょうか?
Re:指定した行に値を書き込む関数
Posted: 2010年6月07日(月) 20:31
by シオン
何度もすみません。
読み込みは何とかできたみたいなのですが
指定した行の文字列を別の文字に変更する方法がわかりません。
又、自作の関数に"%s"等と設定の仕方がわかりません・・・。
どうか教えては頂けないでしょうか?
char buffer[256];
FILE *fp;
fp = fopen("test.txt", "r");
// ファイルオープン失敗か?
if ( !fp ){
//printf("ファイルオープンエラー\n");
//return;
}
// 1行ずつ読み込んで表示する
while( fgets(buffer, 256, fp) ){
printfDx("%s", buffer);
}
// ファイルクローズ
fclose(fp);
Re:指定した行に値を書き込む関数
Posted: 2010年6月08日(火) 01:04
by シオン
自分なりに色々やってみたのですがイマイチわかりません・・・。
void FileSaveX( int index, char string[256] ){
char buffer[10][256];
//int index = 0;
FILE *r_fp;
r_fp = fopen("test.txt", "r");
// ファイルオープン失敗か?
if ( !r_fp ){
//printf("ファイルオープンエラー\n");
//return;
}
// 1行ずつ読み込んで表示する
while( fgets(buffer[index], 256, r_fp) ){
index++;
//printfDx("%s", buffer);
}
// ファイルクローズ
fclose(r_fp);
printfDx("%s", buffer[1]);
FILE *w_fp;
w_fp = fopen( "MapData.txt", "w");
// fprintf( fp, "書き込みたい文字列 ");
fclose(w_fp);
}
Re:指定した行に値を書き込む関数
Posted: 2010年6月08日(火) 04:23
by Ma
全部読み込んだら、各行を順番に書きこみます。(追記モードではなく、全消しして新しく書くモードで。)
行がindexと一致したとき、読み込んだ行を書き込むのではなく、関数に引数としてわたらせた文字列をかきこみます。
これは、for文で作ると一番簡単かと思います。
ちょっと考えてコードを作ってみてください。
*追記
今後、他のファイルで使う事も考えて関数の引数にファイル名も渡すといいと思います。
それから、今は10行までしか格納できませんが、書き込まれている行数が不定で10行以上も考えられる場合は
std::vector 等の、可変長リストを使用するといいと思います。

Re:指定した行に値を書き込む関数
Posted: 2010年6月10日(木) 03:26
by シオン
連絡が遅くなってしまい申し訳御座いませんでした。
ご回答ありがとうございます。
std::vectorを調べてみたのですが使い方がイマイチわかりません。
Re:指定した行に値を書き込む関数
Posted: 2010年6月10日(木) 07:21
by mila
vectorは使用していませんが、ご参考にどうぞ。
#include <stdio.h>
#include <stdarg.h>
int FileSaveX(int index, const char *format, ...)
{
FILE *rfp, *wfp;
int i;
char buf[256];
va_list arg;
if ((rfp = fopen("test.txt", "r")) == NULL) {
return 1;
}
if ((wfp = fopen("MapData.txt", "w")) == NULL) {
fclose(rfp);
return 2;
}
va_start(arg, format);
for (i = 1;; i++) {
if (fgets(buf, sizeof(buf), rfp) == NULL) {
break;
}
if (i == index) {
vfprintf(wfp, format, arg);
fputc('\n', wfp);
} else {
fputs(buf, wfp);
}
}
va_end(arg);
fclose(wfp);
fclose(rfp);
return 0;
}
int main(void)
{
int num = 3;
FileSaveX(1, "あああ%d", num);
return 0;
}
Re:指定した行に値を書き込む関数
Posted: 2010年6月10日(木) 11:53
by バグ
久しぶりにC++で書いてみました。
std::vectorではなく、std::listを使ってみました。
#include <string>
#include <list>
#include <fstream>
////////////////////////////////////////////////////////////////////////////////
// 任意の行に文字列を挿入する
//
// 引数
// unsigned int index = 挿入される行(1以上の数値)
// const char* item = 挿入する文字列
// const char* path = ファイルの場所を示すパス
//
// 戻り値
// true = 正常終了
// false = 以上終了
////////////////////////////////////////////////////////////////////////////////
bool insert_write(unsigned int index, const char* item, const char* path)
{
// インデックスが1未満の場合はfalseを返す
if (index < 1)
{
return false;
}
// 読み込み用ファイルをオープンする
std::ifstream fin;
fin.open(path);
// ファイルオープンに失敗したらfalseを返す
if (fin.is_open() == false)
{
return false;
}
// ファイルの終端まで読み込みつつ、リストへ格納していく
std::string str;
std::list<std::string> lst;
while (fin.eof() == false)
{
str.clear();
fin >> str;
lst.push_back(str);
}
// ファイルのクローズ
fin.close();
// ファイルの最大行数よりも、指定されたインデックスが大きい場合は末尾へ挿入
if (index > lst.size())
{
index = (unsigned int)(lst.size());
}
// イテレータを任意の位置へ進める
std::list<std::string>::iterator it = lst.begin();
for (unsigned int i = 1; i < index; ++i, ++it);
// 文字列を挿入
lst.insert(it, item);
// 書き込み用ファイルをオープン
std::ofstream fout;
fout.open(path);
// ファイルオープンに失敗したらfalseを返す
if (fout.is_open() == false)
{
return false;
}
// リストの内容をファイルへ書き込む
for (it = lst.begin(); it != lst.end(); ++it)
{
if (it->length() > 0)
{
fout << *it << std::endl;
}
}
// ファイルのクローズ
fout.close();
// 正常に終了したのでtrueを返す
return true;
}
Re:指定した行に値を書き込む関数
Posted: 2010年6月14日(月) 00:23
by Justy
どうしてわざわざ C++で書き直したのかは意図はよくわかりませんが、それ正常に動いていないですよ。
fin >> strでは空白類の情報がそげ落ちます。
置き換えるなら getlineでしょう。
>for (unsigned int i = 1; i < index; ++i, ++it);
おかしくはないですが、普通こういう時って標準関数の advanceを使いませんか?
>if (it->length() > 0)
これは変です。オリジナルの行が空行だった場合、その行が出力されなくなります。