如何在C中编写包含换行符作为命令行参数的文本



我想使用C中的系统调用创建一个包含多行的文本文件,并用作为命令行参数提供的文本填充它。

这是我写的:

#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#define MAX_SZ 1024
int main(int argc, char *argv[]) {
if (argc != 3) {
printf("Invalid Number of argumentsn");
printf("USAGE: ./a.out file_name "msg"n");
} else {
int fd_creat, fd_open, fd_write;
char file_name[MAX_SZ];
char *msg = (char *)malloc(strlen(argv[2]) * sizeof(char));
strcpy(file_name, argv[1]);
fd_creat = creat(file_name, 0777);
if (fd_creat < 2) {
printf("ERROR: File could not be createdn");
} else {
fd_open = open(file_name, O_WRONLY);
strcpy(msg, argv[2]);
fd_write = write(fd_open, msg, strlen(msg));
close(fd_open);
}
}
return 0;
}

如果我执行这个程序作为:

./a.out test.txt "FoonBar"

它将整个内容按原样写入test.txt。基本上,我希望"Foo"one_answers"Bar"分别位于它们的行中。

这里有两个问题:

  • 处理参数和未能为所涉及的数据分配足够内存的方式
  • 正确解释像n这样的转义序列,因为shell会按原样、原始地将它们提供给您
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
// This moves overlapping strings from src -> dest but only
// if dest is before src
void cc_str_drag(char* dest, char* src) {
while (*dest) {
*dest = *src;
++dest;
++src;
}
}
// This interprets the n sequence and can be extended to handle others, like
// t, \, or even g.
void cc_interpret(char* str) {
for (;*str; ++str) {
// If this is a sequence start...
if (*str == '\') {
// ...find out which one...
switch (str[1]) {
case 'n':
// Shift back...
cc_str_drag(str, &str[1]);
// ...and replace it.
*str = 'n';
break;
}
}
}
}
int main(int argc, char *argv[]) {
if (argc != 3) {
printf("Invalid Number of argumentsn");
// Remember argv[0] is the name of the program
printf("USAGE: %s file_name "msg"n", argv[0]);
return -1;
}
// Since it's not the 1970s, use fopen() and FILE*
FILE* output = fopen(argv[1], "w");
if (!output) {
printf("ERROR: File could not be createdn");
return -2;
}
// Copying here to avoid tampering with argv
char* str = strdup(argv[2]);
// Replace any escape sequences
cc_interpret(str);
// Then just dump it directly into the file
fwrite(str, 1, strlen(str), output);
fclose(output);
return 0;
}

注意此处使用的工具:

  • strdup是一种比malloc(strlen(s))更快地复制C字符串然后再复制它的方法。这会导致可怕的一个错误
  • FILE*的性能要好得多,因为它是缓冲的。open()用于无法缓冲的低级操作。知道何时使用哪种工具
  • 不要害怕编写操作字符串内容的函数。理解C字符串真的很重要,而不是害怕

最新更新