ファイル入出力と文字列反転処理

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
OI

ファイル入出力と文字列反転処理

#1

投稿記事 by OI » 8年前

こんばんは、ありがとうございます

今私は課題をやっていてその内容が、ファイルを読み込んで各行が反転する加工処理をし、別のファイルに出力するというプログラムを作成しています。
仕様の中の一つ、「データを加工を行ってもファイル内の行数は変わらないものとします」という項目がうまくいきません。
文字列の反転は出来たのですが、改行が変なところに入ったりしてしまい行数が変わってしまいます。
よろしければ原因と解決方法をお教えください。

仕様は以下になります。
<仕様詳細>
・プログラムの起動時にコマンドラインから<入力ファイル><出力ファイル>の順で
各ファイル名を指定できるものとします。
・ユーザの使い方が正しくない場合には、ユーザに使用方法を提示します。
・入力ファイルが見つからなかった場合は、その旨が分かるメッセージを表示します。
・出力ファイルが作成できなかった場合は、その旨が分かるメッセージを表示します。
・入力ファイルに書かれるデータは半角英数字のみとします。
・データを加工を行ってもファイル内の行数は変わらないものとします。
・入力ファイルのサンプルとしてsample_data.txtを使用してください。

入力ファイルサンプル
sample_data.txt

コード:


abcdefghijklmnopqrstuvwxyz

987654321





ファイル入出力と文字列反転処理

コード:

#include <stdio.h>



int main(int argc , char *argv[]){
	FILE *fi,*fo;

	char str[256];
	char reversalStr[256];
	char *pt,*pt1;
	pt = str;
	pt1 = reversalStr;
	int i,j;

	if(argc != 3){
		printf("\n引数の数が違います。\n実行ファイル名 出力元ファイル名 出力先ファイル名 を引数に持たせてください");
	}
	fi=fopen(argv[1],"r");
	if(fi == NULL){
		printf("\nエラー:出力元ファイル名を正しく指定してください。\n");
		return 1;
	}else{
		fo=fopen(argv[2],"w");
		if(fo == NULL){
			printf("\n\n出力先ファイル名の記述を省略した際は出力されません。\n存在しないファイルを指定した場合は新しくファイルが作成されます。\n既にファイルがある場合は上書きされます。\n\n");
		}
	}

	while(fgets(str,256,fi) != NULL){
		
		while(*pt != '\0'){
			pt++;
			i++;
		}
		
		j = i;

		while(i>0){
			pt--;
			*pt1 = *pt;
			pt1++;
			i--;
		}
		*pt1 ='\0';

		fputs(reversalStr,fo);
		//出力確認用のコードprintf("%s",reversalStr);
		while(j>0){
			pt1--;
			j--;
		}

	}
	fclose(fi);
	fclose(fo);
	return 0;
}

box
記事: 2002
登録日時: 13年前

Re: ファイル入出力と文字列反転処理

#2

投稿記事 by box » 8年前

OI さんが書きました: 文字列の反転は出来たのですが、改行が変なところに入ったりしてしまい行数が変わってしまいます。
例題の場合、どんな結果になってしまうのですか?

ところで、何でもかんでもmain関数に詰め込まない方がいいと思います。
少なくとも、ファイルから読んだ文字列を反転させる部分は別の関数にする方が
見通しがよくなると思います。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

OI

Re: ファイル入出力と文字列反転処理

#3

投稿記事 by OI » 8年前

box さんが書きました: 例題の場合、どんな結果になってしまうのですか?

ところで、何でもかんでもmain関数に詰め込まない方がいいと思います。
少なくとも、ファイルから読んだ文字列を反転させる部分は別の関数にする方が
見通しがよくなると思います。
今のままのコードですとこのようにファイルに出力されてしまいます。

コード:



zyxwvutsrqponmlkjihgfedcba

123456789
1と3に本来なら改行がくるのですが3と5に改行が来てしまいます。

ご助言をありがとうございます。今度から少し意識して関数にして作成していこうと思います。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: ファイル入出力と文字列反転処理

#4

投稿記事 by みけCAT » 8年前

fgetsで読み込んだ文字列の中身を見て、最後の文字が改行文字('\n')だったらその部分は反転せずに最後に残すようにするといいと思います。
例:

コード:

     [0] [1] [2] [3]
 in: 'a' 'b' 'c' '\n'
out: 'c' 'b' 'a' '\n'

 in: '0' '1' '2' '3'
out: '3' '2' '1' '0'
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

OI

Re: ファイル入出力と文字列反転処理

#5

投稿記事 by OI » 8年前

[quote=みけCAT]
fgetsで読み込んだ文字列の中身を見て、最後の文字が改行文字('\n')だったらその部分は反転せずに最後に残すようにするといいと思います。[/quote]

最後の行以外にはどの行も最後に改行文字がつくと思うのですが、その改行を処理しないようにしたら一行で出力されないですかね…?
ですがなにかヒントを得た気がするのでお風呂上りにもう一回トライしてみようと思います!

box
記事: 2002
登録日時: 13年前

Re: ファイル入出力と文字列反転処理

#6

投稿記事 by box » 8年前

こんな感じ?

コード:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define N (256)

void usage(void)
{
    printf("Please specify input file and output file as arguments.\n");
}

int getFile(FILE **fp, char *name, char *mode)
{
    *fp = fopen(name, mode);
    return *fp ? 0 : 1;
}

void getReverseString(char *in, char *out)
{
    int i;

    for (i = 0; i < strlen(in); i++) {
        out[i] = in[strlen(in) - 1 - i];
    }
    out[i] = '\0';
}

void processFile(FILE *fi, FILE *fo)
{
    char in[N], out[N];

    while (fgets(in, N, fi)) {
        in[strlen(in) - 1] = '\0';
        getReverseString(in, out);
        fprintf(fo, "%s\n", out);
    }
    fclose(fi), fclose(fo);
}

int main(int argc, char **argv)
{
    FILE *fi, *fo;

    if (argc != 3) {
        usage();
        exit(1);
    }
    if (getFile(&fi, argv[1], "r") == 1 || getFile(&fo, argv[2], "w") == 1) {
        printf("You specified invalid file.\n");
        exit(1);
    }
    processFile(fi, fo);
    return 0;
}
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

かずま

Re: ファイル入出力と文字列反転処理

#7

投稿記事 by かずま » 8年前

box さんが書きました:

コード:

    for (i = 0; i < strlen(in); i++) {
        out[i] = in[strlen(in) - 1 - i];
    }
Kernighan & Pike の The Practice of Programmingからです。
strlen(s) について、This apparently linear algorithm for scanning a string, ??? is the fact quadratic: ... と言っています。
「一見すると文字列スキャン用の 1次アルゴリズムに見えるが、実際には 2次アルゴリズムだ」
O(n) のみたいだが、O(n2) ということです。

かずま

Re: ファイル入出力と文字列反転処理

#8

投稿記事 by かずま » 8年前

OI さんが書きました: 文字列の反転は出来たのですが、改行が変なところに入ったりしてしまい行数が変わってしまいます。
よろしければ原因と解決方法をお教えください。
問題点
  • みけCATさんの指摘通り、'\n' を反転の対象にしている
  • i が初期化されていない
  • 最初の 3つのエラーチェックのうち、return 1; はひとつだけ
参考までに.

コード:

#include <stdio.h>
 
int main(int argc , char *argv[])
{
    FILE *fi, *fo;
    char str[256];
    char *pt, *pt1;
 
    if (argc != 3) { printf("usage: %d infile outfile\n", argv[0]); return 3; }
    fi = fopen(argv[1], "r");
    if (fi == NULL) { printf("can't open %s\n", argv[1]); return 1; }
    fo = fopen(argv[2], "w");
    if (fo == NULL) { printf("can't create %s\n", argv[2]); return 2; }
 
    while (fgets(str, 256 , fi) != NULL) {
        for (pt = str; *pt && *pt != '\n'; pt++) ;
        pt1 = pt;
        while (pt > str) putchar(*--pt);
        if (*pt1) putchar(*pt1);
    }
    fclose(fi);
    fclose(fo);
    return 0;
}

かずま

Re: ファイル入出力と文字列反転処理

#9

投稿記事 by かずま » 8年前

かずま さんが書きました:
OI さんが書きました:

コード:

        while (pt > str) putchar(*--pt);
        if (*pt1) putchar(*pt1);
訂正です。

コード:

        while (pt > str) putc(*--pt, fo);
        if (*pt1) putc(*pt1, fo);

閉鎖

“C言語何でも質問掲示板” へ戻る