我正在K& R做练习:
编写一个程序detab,用空格中适当数量的空格替换输入中的制表符到下一个制表位。
这就是我到目前为止(没有对文件进行错误检查):
#include <stdio.h>
#define tab 2
#define MAX_LENGTH 1000
int main(int argc, char **argv)
{
FILE *fp = fopen(argv[1], "r+");
int c, n;
char buffer[MAX_LENGTH + 1];
for (n = 0; n < MAX_LENGTH && (c = fgetc(fp)) != EOF; ++n) {
if (c == '\t') {
for (int x = 0; x < tab; ++x)
buffer[n++] = ' ';
--n;
}
else
buffer[n] = c;
}
//buffer[n] = '\0';
//rewind(fp);
//fputs(buffer, fp);
printf("%s\n", buffer);
fclose(fp);
return 0;
}
它似乎有效,但我想知道为什么最后不需要\0
。我只是幸运吗?
答案 0 :(得分:5)
是的,你很幸运。为避免此问题,您可以使用fwrite
,它不需要空终止符(因为您准确指定要写入的字节数):
fwrite(buffer, 1, n, stdout);
答案 1 :(得分:4)
您可以告诉printf(...)
要为给定字符串打印的(最大)字符数。
printf("%.*s\n", n, buffer);
请参阅printf(3),“精确度”部分:
一个可选的精度,以句点('。')的形式后跟一个可选的 十进制数字串。可以写“*”而不是十进制数字字符串 [...]指定精度给出 下一个参数[...],必须是int类型。 [...] 这给出了要从a打印的最大字符数 s [...]转换的字符串。
printf ("%.*s\n", 5, "Hello, world!")
的实时演示:http://ideone.com/KHKLl。
答案 2 :(得分:2)
您可以使用以下命令初始化缓冲区:
memset(buffer, '\0', MAX_LENGTH + 1);
你不必担心空终止。
答案 3 :(得分:1)
正如其他答案所指出的,你很幸运,数组在正确的位置包含空值。
您可以使用此简写创建它时初始化它:
char buffer[MAX_LENGTH + 1] = { 0 }; // all elements will be zero
请注意,这是因为编译器会使用零初始化未指定的条目 - 所以如果你说
char buffer[MAX_LENGTH + 1] = { 'a' };
然后数组将是{'a',0,0,0....}