2016-03-28 8 views
0

私は、パラメータ行からその行の1行をプリプロセッサ定数として#defineされたローカル文字配列バッファに読み込む関数void reverse_file(FILE * file)を書く必要がありますMAXLINE。各行に対して、この関数は前のreverse_string関数を呼び出して行を逆転させ、逆の行を標準出力に書き込みます。与えられたファイルから行を逆転させる

私はreverse_string方法

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

void reverse_String(char* str); 
int main() 
{ 
    char str [256]; 
    strcpy_s(str, "Hello"); 
    reverse_String(str); 
    return 0; 
} 
void reverse_String(char* str) 
{ 
    int i, j; 
    char temp; 
    i=j=temp=0; 

    j=strlen(str)-1; 
    for (i=0; i<j; i++, j--) 
    { 
     temp=str[i]; 
     str[i]=str[j]; 
     str[j]=temp; 
    } 
    printf("%s",str); 
} 

を持っている私はちょうどreverse_file(FILE *ファイル)の部分で助けが必要。

何か助けていただければ幸いです。

+0

は、あなたが3行のファイルがあるとします。 'cba'、' fed'、 'ihg'、' ghi'、 'def'、' abc'、あるいは 'ihg'、' fed''、 'cba'を出力する必要がありますか?かかわらず、必要な出力が何であるかの、あなたは、標準のC [ 'のfgets()'](http://pubs.opengroup.org/onlinepubs/9699919799/functions/fgets.html)またはPOSIX [ 'getlineのを(ルックアップする必要があります) '](http://pubs.opengroup.org/onlinepubs/9699919799/functions/getline.html)を参照してください。次に、必要に応じて逆文字列関数を呼び出します。通常、出力を反転から分離する方がよいことに注意してください。 –

+1

また、 'printf(str)'は悪いです。非常に悪いです。 'printf("%s \ n "、str)'や 'puts(str)'を使うべきです。印刷している文字列に '%'シーケンスが含まれていて、それらの '%s'シーケンスを処理するために' printf() 'に引数を指定しなかった場合、危険です。 –

+0

@JonathanLeffler第2のもの。 abcはcbaになります –

答えて

1

多分このような何か?

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

void reverse_String(char* str) 
{ 
    int i, j; 
    char temp; 
    i=j=temp=0; 

    j=strlen(str)-1; 
    for (i=0; i<j; i++, j--) { 
     temp=str[i]; 
     str[i]=str[j]; 
     str[j]=temp; 
    } 
    printf("%s",str); 
} 

void reverse_File(FILE* file) { 
    char* line; 
    size_t len = 0; 
    ssize_t read; 

    while ((read = getline(&line, &len, file)) != -1) { 
     reverse_String(line); 
    } 
} 

int main(void) { 

    FILE * fp; 

    fp = fopen("Maze.txt", "r"); 

    if (fp == NULL) 
     exit(EXIT_FAILURE); 

    reverse_File(fp); 
} 
+0

、感謝を忘れてしまった ' '\ n''で始まります各逆にラインを意味getline''によって読み取られる各 'line'から改行*行指向*入力を使用している場合。あなたはいつも ' '\ n''または'' \ rを\ n''(DOS/Windowsの場合)、末尾を削除する必要があります。 –

+0

たくさんの感謝の人にこの作品 –

+0

かなりきちんとし。マイナーな問題のカップル。(1)あなた'line'を安全に' free() 'に渡すことができるはずです([getline()'](http://pubs.opengroup.org/onlinepubs/9699919799/functions/getline.html)による :_アプリケーションは '* lineptr'が' free() '関数に渡すことができる有効な引数であることを保証しなければならないので、' line'を0に設定することは良い考えです。 (2) 'getline()'で確保された(おそらく)メモリを解放するべきです。ファイルが空であっても、最初の読み取り操作で '-1'が返されます。また、行末も処理する必要があります。 –

1

あなたは既に細かい回答がありますが、考慮すべき点はいくつかあります。あなたは行指向入力方法(fgetsまたはgetline)を使用している場合は、'\n'または'\r\n'(DOS/Windowsの場合)行末の読み取りを削除し、fgetsまたはgetlineいずれかによって元の行に含まれなければなりません。 (これが、元のファイルの出力に最初の空白行がある理由です)。

行末を削除する簡単な方法は、末尾のいずれかの行末の最初の行を、ヌル終端の文字で上書きすることです。これを行うには、あなたのメイン・プログラム・ロジックは、次のようになります。

while (fgets (str, MAXC, fp)) {  /* read each line */ 
    rmcrlf (str);     /* trim \r or \n */ 
    strrev (str);     /* reverse string */ 
    printf ("%s\n", str);   /* output reverse */ 
} 

あなたrmcrlf次のようになります(キャリッジリターン改行は削除):

/** stip trailing newlines and carraige returns by overwriting with 
* null-terminating char. 's' is modified in place. 
*/ 
void rmcrlf (char *s) 
{ 
    if (!s || !*s) return;   /* validate not NUL and not empty */ 
    char *p = strpbrk (s, "\r\n"); /* locate first line-ending char */ 
    *p = 0;       /* set to nul-terminating char */ 
} 

(注:あなたが使用することができstrlen (またはポインタとループ)を使用して文字列の末尾を検索し、逆方向に処理しますが、は、末尾を検索せずに逆方向に'\n'または'\r'のいずれかを検索することができます。

その後、次のようにあなたは一緒にすべてのピースを置くことができ

/** strrev - reverse string 's' in place. 
* The original string is not preserved. 
* If 's' is not valid, no action taken. 
*/ 
void strrev (char *s) 
{ 
    if (!s || !*s) { /* validate s not NUL and not empty */ 
     printf ("strrev() error: invalid string\n"); 
     return; 
    } 

    char tmp; 
    char *begin = s, *end = strrchr (s, 0) - 1; 

    while (end > begin) { 
     tmp = *end; 
     *end-- = *begin; 
     *begin++ = tmp; 
    } 
} 

同じように場所に文字列を逆に(代わりにstrlenの終わりを見つけることstrrchrを使用して)することができます。これは同じタスクにアプローチする単純な別の方法です。注:次のコードでは、#defineの代わりにenumを使用して定数を設定します(代わりの方法を示すため)。また、注意してください:コードは最初の引数として与えられたファイルから読み込まれることを(またはstdinから、デフォルトでは、ファイル名が与えられていない場合):

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

enum { MAXC = 256 }; 

void strrev (char *s); 
void rmcrlf (char *s); 

int main (int argc, char **argv) { 

    char str[MAXC] = ""; 
    FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin; 

    if (!fp) { /* validate file is open */ 
     fprintf (stderr, "error: file open failed '%s'.\n", argv[1]); 
     return 1; 
    } 

    while (fgets (str, MAXC, fp)) {  /* read each line */ 
     rmcrlf (str);     /* trim \r or \n */ 
     strrev (str);     /* reverse string */ 
     printf ("%s\n", str);   /* output reverse */ 
    } 

    if (fp != stdin)   /* close file (if not stdin) */ 
     fclose (fp); 

    return 0; 
} 

/** strrev - reverse string 's' in place. 
* The original string is not preserved. 
* If 's' is not valid, no action taken. 
*/ 
void strrev (char *s) 
{ 
    if (!s || !*s) { /* validate s not NUL and not empty */ 
     printf ("strrev() error: invalid string\n"); 
     return; 
    } 

    char tmp; 
    char *begin = s, *end = strrchr (s, 0) - 1; 

    while (end > begin) { 
     tmp = *end; 
     *end-- = *begin; 
     *begin++ = tmp; 
    } 
} 

/** stip trailing newlines and carraige returns by overwriting with 
* null-terminating char. 's' is modified in place. 
*/ 
void rmcrlf (char *s) 
{ 
    if (!s || !*s) return; 
    char *p = strpbrk (s, "\r\n"); 
    *p = 0; 
} 

例入力

$ cat dat/strtorev.txt 
abc def ghi jkl mno pqr 
ABC DEF GHI JKL MNO PQR 

出力を

$ ./bin/strrev_line <dat/strtorev.txt 
rqp onm lkj ihg fed cba 
RQP ONM LKJ IHG FED CBA 

(注意:ジョナサンはコメントで尋ねたとして、あなたはどちらか上記のように行を逆にするか、各単語を逆にすることができます(例: cba fed ihg...)は、必要なことが正しく記述されているかどうかを確認してください。

は、ご質問があれば私に教えてください。 `abc`、` def`、 `ghi`:

+0

これは本当に感謝しています。 –

+0

確かに、喜んで助けてください。ちょうどいくつかの緩い終わりをきれいにする。あなたのコーディングに幸運を祈る。 –

関連する問題