[英]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)为什么复制的行被混合在一起,而不是在新行上干净地打印? fgets
和puts不应该一次读/写 1 行吗? 特别是因为我知道每行的最大长度是多少。 (我也尝试使用scanf()
、 printf()
、 write()
,但这些都没有区别)。
3) 如果我成功使用fdopen(, "a")
,我就不需要使用dup2
和lseek
,对吗?
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.