現在 テキストファイル処理について悩んでおります。
C言語初心者です。
フォルダにはいくつものテキストファイルがあります。(500くらい)
そのテキストファイルを一括処理したいです。
処理の内容は
まず一行目のタイトルを削除し、いくつもの数字を一行表示にしたいです。
またその際に出力ファイル名も指定 (0001 0002 0003 ....) したいです。
C言語でこのようなプログラミングは可能でしょうか?
テキストの中身は
________________________________
Test
1110.02034 4444.33454 23434.2292 29.49349
12.394323443 94.545432 94.43434 9123432
243490 203942 49204
33322003 32049324 3030 230209
_________________________________
出力したい結果は
_________________________________
1110.02034 4444.33454 23434.2292 29.49349 12.394323443 94.545432 94.43434 9123432 ......
________________________________
テキストファイル処理について
Re: テキストファイル処理について
そりゃまあ何でもできるといえばできますが、tomoya さんが書きました: まず一行目のタイトルを削除し、いくつもの数字を一行表示にしたいです。
またその際に出力ファイル名も指定 (0001 0002 0003 ....) したいです。
C言語でこのようなプログラミングは可能でしょうか?
「いくつもの数字」→いくつなんですか?固定ですか?可変ですか?
「出力ファイル名を指定」→どこからどこまでをどのファイルに出力するか、どうやって判断するんですか?
というような、仕様の不明確な部分を明確にしていただく必要があるかもしれません。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。
プログラムは思ったとおりには動かない。書いたとおりに動く。
-
ゆうたろう
Re: テキストファイル処理について
試していませんがこんな感じでできます↓
FILE *fp = fopen(nextopen, "r");
if (fp == NULL) {
printf("file open error!!\n");
exit(EXIT_FAILURE);
}
//1行読みとばす
while(getc(fp)!='\n');
while ( fgets(dainyuu, 256, fp ) !=NULL)
{
sscanf(dainyuu,"%f %f %f %f", murabito[m].message , murabito[m].gazou , &murabito[m].x , &murabito[m].y );
m++;
}
FILE *fp = fopen(nextopen, "r");
if (fp == NULL) {
printf("file open error!!\n");
exit(EXIT_FAILURE);
}
//1行読みとばす
while(getc(fp)!='\n');
while ( fgets(dainyuu, 256, fp ) !=NULL)
{
sscanf(dainyuu,"%f %f %f %f", murabito[m].message , murabito[m].gazou , &murabito[m].x , &murabito[m].y );
m++;
}
-
tomoya
Re: テキストファイル処理について
いくつもの回答ありがとうございます。
「いくつもの数字」→可変です。
テキストファイルの中身の数字は固定ではありません。
「出力ファイル名を指定」 test1 →00001 変換
元のテキストファイル名は test1 だとすると
出力ファイル名を 00001 に変換したいです。
それらの作業をフォルダ内にあるすべてのテキストファイルに処理がしたいです。
Microsoft Visual Studio2010を使用しています。
「いくつもの数字」→可変です。
テキストファイルの中身の数字は固定ではありません。
「出力ファイル名を指定」 test1 →00001 変換
元のテキストファイル名は test1 だとすると
出力ファイル名を 00001 に変換したいです。
それらの作業をフォルダ内にあるすべてのテキストファイルに処理がしたいです。
Microsoft Visual Studio2010を使用しています。
Re: テキストファイル処理について
ファイル名が一連番号のようについていて、既知なのか、それともフォルダに入っているファイル名はtomoya さんが書きました:フォルダにはいくつものテキストファイルがあります。(500くらい)
バラバラでフォルダに入っているファイルをすべて処理したいのかによります。
前者なら良いですが、後者なら、findfirstfileなどを使って、ファイル名を取得する必要があります。
non
-
かずま
Re: テキストファイル処理について
各行が何をしているのかを調べて、理解してください。
分からなければ、どの部分が分からないのか質問してください。
分からなければ、どの部分が分からないのか質問してください。
#include <stdio.h>
#include <string.h>
#include <windows.h>
int proc(const char *infile)
{
FILE *fpi, *fpo; char outfile[12]; int c;
if (sscanf(infile, "%*[^0-9]%d", &c) != 1)
return fprintf(stderr, "number not found in %s\n", infile), 1;
sprintf(outfile, "%05d", c);
fpi = fopen(infile, "r");
if (!fpi) return fprintf(stderr, "can't open %s\n", infile), 1;
fpo = fopen(outfile, "w");
if (!fpo) return fprintf(stderr, "can't create %s\n", outfile), 1;
while ((c = fgetc(fpi)) != EOF && c != '\n') ;
while ((c = fgetc(fpi)) != EOF) fputc(c == '\n' ? ' ' : c, fpo);
fclose(fpi);
fclose(fpo);
return 0;
}
int main(int argc, char *argv[])
{
WIN32_FIND_DATA fd; HANDLE h;
if (argc != 2)
return fprintf(stderr, "usage: %s diretoryname\n", argv[0]), 1;
if (!SetCurrentDirectory(argv[1]))
return fprintf(stderr, "can't set directory: %s\n", argv[1]), 1;
h = FindFirstFile("*", &fd);
if (h == INVALID_HANDLE_VALUE)
return fprintf(stderr, "can't get file names\n"), 1;
do {
if (strcmp(fd.cFileName, ".") && strcmp(fd.cFileName, ".."))
proc(fd.cFileName);
} while (FindNextFile(h, &fd));
FindClose(h);
return 0;
}
-
かずま
Re: テキストファイル処理について
訂正です。 あと気になるのが、test1, test2, ..., test500 を変換して
00001, 00002, ..., 00500 を同じディレクトリに書いていることです。
FindFirstFile がその実行時点でのディレクトリ情報をすべて読み込んで、
あとは FindNextFile がその情報を使うのならいいんですが、
FindFirstFile で一部の情報しか読み込ます、FindNextFile で追加情報を
読み込むのなら、新たに書き出した 00001, 00002, ... なども入力ファイルの
対象になってしまうかもしれません。sscanf の書式が 数字以外が 1文字以上で
そのあとに数字が来るものなので、実際には入力ファイルとなりませんが、
エラーメッセージが出てしまいます。
500個のファイルで試してみたところ、幸いそういう現象は出ませんでした。
でも、念のために、出力は別のディレクトリにしたほうがよいかもしれません。
ところで、最初の質問者はフォルダという言葉を使っていますが、
それがディレクトリと同じだということを理解されていますか?
フォルダというのは、Windows のような GUI が一般的になってから
ディレクトリをアイコンで表示したときにその名称を使い始めたようです。
OS の API は Windows なら SetCurrentDiretory、Linux などは chdir (change
diretory) となっています。
Re: テキストファイル処理について
C言語のソースコードだと全体的な流れを追いづらいだろうと思ったので、python版を作ってみました。
まったく読める気がしない、というのであれば無理に読んで理解する必要はありません。
ただ基本的な処理の流れはC言語で書く場合と大差ないので、理解の助けになるかもしれないと思って書きました。
re.compile(r'\D+(\d+)')
という部分が少しややこしいかもしれないので解説しておきます。
\D+(\d+) は正規表現といいます。
「\D」が「数字ではない文字」を表し、「\d」が「数字(0〜9)」を表します。「+」が「1文字以上」を表します。
\D+(\d+) 全体で「数字ではない文字が1文字以上続いた後に、数字が1文字以上続く文字列」を表します。
例えば test1, test2, foo_bar0123 のようなものが一致し、 test1a, foo_bar0123_hoge のようなものは一致しません。
\d+を括弧で囲んでいるのは、後に m.group(1) でその部分を取り出すためです。
括弧で囲むと後で取り出せるわけです。
今回の場合、m.group(1)では
test1 であれば 1
foo_bar0123 であれば 0123
を取り出すことができます。
まったく読める気がしない、というのであれば無理に読んで理解する必要はありません。
ただ基本的な処理の流れはC言語で書く場合と大差ないので、理解の助けになるかもしれないと思って書きました。
import os
import re
def Conv(in_file_name, out_file_name):
f = open(in_file_name)
fo = open(out_file_name, 'w')
line = f.readline()
line = f.readline()
while line:
fo.write(line[:-1])
line = f.readline()
if line:
fo.write(' ')
files = os.listdir('.')
file_name_regex = re.compile(r'\D+(\d+)')
for file in files:
m = file_name_regex.match(file)
if m:
num = int(m.group(1))
Conv(file, '%04d' % (num,))
という部分が少しややこしいかもしれないので解説しておきます。
\D+(\d+) は正規表現といいます。
「\D」が「数字ではない文字」を表し、「\d」が「数字(0〜9)」を表します。「+」が「1文字以上」を表します。
\D+(\d+) 全体で「数字ではない文字が1文字以上続いた後に、数字が1文字以上続く文字列」を表します。
例えば test1, test2, foo_bar0123 のようなものが一致し、 test1a, foo_bar0123_hoge のようなものは一致しません。
\d+を括弧で囲んでいるのは、後に m.group(1) でその部分を取り出すためです。
括弧で囲むと後で取り出せるわけです。
今回の場合、m.group(1)では
test1 であれば 1
foo_bar0123 であれば 0123
を取り出すことができます。