繁体   English   中英

C:读取txt文件,按大小写重定向+追加到新文件

[英]C: read txt file, redirect + append to new files by case

我有一个输入 txt 文件,其中每第三行(“指令”行)最多 4 个字节,接下来的两行(“数据”行)每行最多 16 个字节。

如果指令行中的最后一个字符是字母,我想将该行以及接下来的 2 行数据复制到新创建的文件“letter_in.tmp”中。 如果最后一个字符是数字,我只想将该指令行复制到文件“number_in.tmp”,但跳过 2 个数据行。

如果可能的话,我想使用重定向来做到这一点,尽管这不是必需的。 这是我写的:

#define LETTER "letter_in.tmp"
#define NUMBER "number_in.tmp"
#define BUFSIZE 17

//argv[1] will be inputFile.txt
int main(int argc, char* argv[])
{
    if (argc != 2)
        usage_err(argc);

    int sav_stdin = dup(0);
    int sav_stdout = dup(1);

    redirect_files(argv[1]);

    return 0;
}


void redirect_files(char* inputF)
{
    FILE* fp = fopen(inputF, "r");

    char buffer[BUFSIZE];
    int fd_LetterIn = open_file(LETTER);
    int fd_NumberIn = open_file(NUMBER);

    //fdopen(fd_LetterIn, "a");
    //fdopen(fd_NumberIn, "a"); 

    unsigned char lastChar;

    while(fgets(buffer, sizeof(buffer), fp) != NULL) 
    {
        lastChar = isLetter(buffer[strlen(buffer) - 1]);
        if (lastChar == 1) //last character is a letter, so copy 3 lines to "letter_in.tmp"
        {
            dup2(fd_LetterIn, 1);
            lseek(fd_LetterIn, 0, SEEK_END);
            puts(buffer);
            fgets(buffer, sizeof(buffer), fp);
            puts(buffer);
            fgets(buffer, sizeof(buffer), fp);
            puts(buffer);
        }

        else
        {
            dup2(fd_NumberIn, 1);
            lseek(fd_NumberIn, 0, SEEK_END);
            write(fd_NumberIn, buffer, sizeof(buffer));
            fgets(buffer, sizeof(buffer), fp);
            fgets(buffer, sizeof(buffer), fp);
        }
    }
}

int open_file(char* name)
{
    int fd;
    fd = open(name, O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR);
    if (fd < 0)  // open failed
    {
        fprintf(stderr, "ERROR: open \"%s\" failed (%d). Exiting\n", name, fd);
        exit(2);
    }
    fprintf(stderr, "opened file %s, file descriptor is: %d\n", name, fd);
    return(fd);
}

示例输入inputFile.txt

3da
000a050a0a050a00
0000000005000005
1de
000a050a0a050a00
000005fb0002fb05
3e2
ec0af60a000000f6
f6ececece2f6e200
362
f600fbfb00fb0a00
0a05000afb0af605
195a
00f6fbf6f6fbf600
00000000fb0000fb

这就是我最终得到的结果:

在此处输入图片说明

在此处输入图片说明

1) 为什么一切都只写入number_in.tmp

2)为什么复制的行被混合在一起,而不是在新行上干净地打印? fgetsputs不应该一次读/写 1 行吗? 特别是因为我知道每行的最大长度是多少。 (我也尝试使用scanf()printf()write() ,但这些都没有区别)。

3) 如果我成功使用fdopen(, "a") ,我就不需要使用dup2lseek ,对吗?

4) 假设从redirect_files() ,我将标准输入/输出重定向到某个文件,但在函数结束时不要将其改回。 当我跳回main() ,标准输入/输出是否仍指向重定向的文件,还是与调用redirect_files()之前相同?

您总是将\\n传递给isLetter函数,请注意fgets\\n附加到缓冲区。

    lastChar = isLetter(buffer[strlen(buffer) - 1]);

应该

    lastChar = isLetter(buffer[strlen(buffer) - 2]); //Add boundary checks.

在写作时你应该使用strlen而不是sizeof ,否则你最终会写出垃圾。

        write(fd_NumberIn, buffer, strlen(buffer));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM