我必须编写一个函数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 *文件)部分的帮助。
感谢任何帮助。
答案 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)
你已经有了一个很好的答案,但有一些细微的要点需要考虑。如果您使用面向行的输入法(fgets
或getline
),则应删除'\n'
或'\r\n'
(DOS /窗口)行尾读取并包含在fgets
或getline
的原始行中。 (这就是原始文件输出中有一个初始空行的原因)。
删除行结尾的一种简单方法是简单地用 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...
)确保您已正确说明您需要做什么,如果不是我们可以进一步帮助。)
如果您有任何问题,请与我们联系。