从给定参数

时间:2016-03-28 03:43:10

标签: c string function file

我必须编写一个函数void reverse_file(FILE * file),它将参数文件中的行一行读入一个本地字符数组缓冲区,其大小为#defined,作为预处理器常量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 *文件)部分的帮助。

感谢任何帮助。

2 个答案:

答案 0 :(得分: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);
}

答案 1 :(得分:1)

你已经有了一个很好的答案,但有一些细微的要点需要考虑。如果您使用面向行的输入法(fgetsgetline),则应删除'\n''\r\n'(DOS /窗口)行尾读取并包含在fgetsgetline的原始行中。 (这就是原始文件输出中有一个初始空行的原因)。

删除行结尾的一种简单方法是简单地用 nul-terminatedating 字符覆盖第一个遇到的行尾。为此,您的主程序逻辑将如下所示:

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(或指针和循环)查找字符串的结尾并向后工作,但strpbrk允许您搜索'\n''\r'向前方向,无需找到结束并向后工作)

然后,您可以采用相同的方式撤消字符串(但使用strrchr查找结尾而不是strlen

/** 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;
    }
}

您可以将所有部分放在一起,如下所示。这只是处理同一任务的另一种方式。注意:以下代码使用enum而不是#define来设置定义常量(仅显示替代方法)。另请注意:代码将从作为第一个参数给出的文件中读取(如果没有给出文件名,则默认来自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

(注意:正如Johnathan在评论中提到的那样,您可以如上所示反转该行,或者您可以反转每个单词(例如cba fed ihg...)确保您已正确说明您需要做什么,如果不是我们可以进一步帮助。)

如果您有任何问题,请与我们联系。