C - 通过基本I / O读取只读“\ n”

时间:2013-10-27 09:17:12

标签: c terminal newline output reverse

我的C-lecture技能练习有问题。我的练习是读取一个文本文档(与程序在同一目录中)char by char并在终端上将其反转(所以从头到尾,char by char)(我必须在Ubuntu工作) 。

不幸的是它不起作用 - “read”只读取换行符(\ n)。

你能找到我的错误吗?

#include <sys/stat.h> //mode_t: accessing rights for the file
#include <fcntl.h>   //for I/O
#include <unistd.h>  //for file descriptors
#include <string.h>  //for strlen


short const EXIT_FAILURE = 1;
short const EXIT_SUCCESS = 0;

char const* USAGE_CMD = "usage: write_file filename string_to_write\n";
char const* ERR_OPEN  = "error in open\n";
char const* ERR_READ  = "error in reading\n";
char const* ERR_CLOSE = "error in close\n";
char const* ERR_WRITE = "error in write\n";

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

    int fd = open(argv[1], O_RDONLY);
    if(fd == -1){
        write(STDERR_FILENO, ERR_OPEN, strlen(ERR_OPEN));
        return EXIT_FAILURE;
    }

    int two_char_back = (-1)*sizeof(char);      //shift-value for char
    int one_back = -1;                              //shift-value for "no shift"
    int length = lseek(fd, one_back, SEEK_END);//setting to one before oef
    int i = 0;                                          //for the loop
    char buffer;
    char* pbuffer = &buffer;                        //buffer for writing
    while (i < length){
        if (read(fd, pbuffer, sizeof(buffer)) == -1){   //READING
            write(STDERR_FILENO, ERR_READ, strlen(ERR_READ));
            return EXIT_FAILURE;
        }

        if(write(STDOUT_FILENO, pbuffer, sizeof(buffer)) == -1){    //WRITING
            write(STDERR_FILENO, ERR_WRITE, strlen(ERR_WRITE));
            return EXIT_FAILURE;
        }

    lseek(fd, two_char_back, SEEK_CUR);         //STEPPING
    i++;
    }

    if(close(fd) == -1){                                //CLOSING
        write(STDERR_FILENO, ERR_CLOSE, strlen(ERR_CLOSE));
        return EXIT_FAILURE;    
    }

return EXIT_SUCCESS;

}

4 个答案:

答案 0 :(得分:1)

这是错误的:

int two_char_back = (-1)*sizeof(char);

sizeof(char)为1,你需要-2

答案 1 :(得分:1)

没有尝试过运行它,但看起来像two_char_back应该是-2。读取使光标前进,因此-1继续读取相同的光标。

另外,只是一个选项,您可以通过读取整个文件然后将其反转然后写入来提高效率。

答案 2 :(得分:1)

您在以下行中输入错字:

int two_char_back = (-1)*sizeof(char);

必须是:

int two_char_back = (-2)*sizeof(char); 

read()增加光标时,你实际上是在一直读取相同的字符,例如:

example text
           ^
           |

阅读后:

example text
            ^
            |

寻求:

example text
           ^
           |

答案 3 :(得分:0)

非常感谢您的建议! &安培;感谢我的同事们!

现在它可以工作,但我创建了一个新版本,这里是:

#include <sys/stat.h> //mode_t: accessing rights for the file
#include <fcntl.h>   //for I/O
#include <unistd.h>  //for file descriptors
#include <string.h>  //for strlen


short const EXIT_FAILURE = 1;
short const EXIT_SUCCESS = 0;

char const* USAGE_CMD = "usage: write_file filename string_to_write\n";
char const* ERR_OPEN  = "error in open\n";
char const* ERR_READ  = "error in reading\n";
char const* ERR_CLOSE = "error in close\n";
char const* ERR_WRITE = "error in write\n";

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

    int fd = open(argv[1], O_RDONLY);           //OPENING
    if(fd == -1){
        write(STDERR_FILENO, ERR_OPEN, strlen(ERR_OPEN));
        return EXIT_FAILURE;
    }

    int file_size = lseek(fd, 0, SEEK_END); //setting to eof
    int i = file_size-1;                        //for the loop, runs from the end to the start
    char buffer;
                                                    //the files runs from the end to the back
    do{
        i--;
    lseek(fd, i, SEEK_SET);                                     //STEPPING from the start

        if (read(fd, &buffer, sizeof(buffer)) != sizeof(buffer)){   //READING
            write(STDERR_FILENO, ERR_READ, strlen(ERR_READ));
            return EXIT_FAILURE;
        }
        if(write(STDOUT_FILENO, &buffer, sizeof(buffer)) != sizeof(buffer)){    //WRITING
            write(STDERR_FILENO, ERR_WRITE, strlen(ERR_WRITE));
            return EXIT_FAILURE;
        } 
    }while (i != 0);

    buffer = '\n';
    write(STDOUT_FILENO, &buffer, sizeof(buffer));//no error-det. due to fixed value

    if(close(fd) == -1){                                //CLOSING
        write(STDERR_FILENO, ERR_CLOSE, strlen(ERR_CLOSE));
        return EXIT_FAILURE;    
    }

return EXIT_SUCCESS;

}