1

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

不幸的是,它不起作用 - “读取”只读取换行符 (\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

4 回答 4

1

这是错误的:

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

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

于 2013-10-27T09:27:43.547 回答
1

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

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

于 2013-10-27T09:29:56.657 回答
1

您在以下行中有错字:

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

一定是:

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

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

example text
           ^
           |

看完后:

example text
            ^
            |

寻求后:

example text
           ^
           |
于 2013-10-27T09:34:55.500 回答
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;

}
于 2013-10-27T17:51:38.080 回答