循环中 printf 的 Getline 行为
Getline behavior with printf in loop
为什么我需要敲两次回车才能改变当前目录?我注意到,如果我更改循环中 printf 语句的位置,行为就会发生变化。我不明白这是为什么。
下面的工作代码。它在 Ubuntu 系统上编译。它的工作量很小。其中大部分是手册页中的用法。
#define _GNU_SOURCE // http://man7.org/linux/man-pages/man3/getline.3.html
#include <stdio.h>
#include <unistd.h> // http://man7.org/linux/man-pages/man3/getcwd.3.html
int main() {
char *line = NULL;
size_t linecap = 0;
ssize_t linelen;
while ((linelen = getline(&line, &linecap, stdin)) > 0) {
char * buf = NULL;
size_t size = 1000;
char * s = getcwd(buf, size);
printf("%s# ", s);
*(line+linelen-1) = '[=10=]';
chdir(&line[3]);
}
return 0;
}
我没有得到程序的输出,我在下面显示了这一点(首先,我需要按一次回车键来获得提示——这没关系,并且是为这个例子准备的)。
/path/to/dir# cd ..
/path/to/dir#
/path/to#
您的循环执行以下逻辑:
- 等待用户输入
- 打印当前目录
- 更改当前目录
因此每次输入用户输入时,它都会显示旧目录、更改目录(没有可见输出)然后等待新输入。这确实是您的示例输出显示的内容。
要获得您想要的行为,请移动 getcwd
并向下显示到 chdir
调用下方。
请注意,如果此人随后输入了一个短于 3 的字符串(例如,他们再次按下 Enter,我在测试时做了,你也是),你仍然会继续调用 chdir(&line[3]);
,导致意外结果(可能UB) 因为这已经过了字符串的末尾。在我的系统上它重复了 chdir("..")
。要解决此问题,您可能应该检查 linelen >= 3
(并且它确实以 cd
开头),如果不是,则不要调用 chdir
。
为什么我需要敲两次回车才能改变当前目录?我注意到,如果我更改循环中 printf 语句的位置,行为就会发生变化。我不明白这是为什么。
下面的工作代码。它在 Ubuntu 系统上编译。它的工作量很小。其中大部分是手册页中的用法。
#define _GNU_SOURCE // http://man7.org/linux/man-pages/man3/getline.3.html
#include <stdio.h>
#include <unistd.h> // http://man7.org/linux/man-pages/man3/getcwd.3.html
int main() {
char *line = NULL;
size_t linecap = 0;
ssize_t linelen;
while ((linelen = getline(&line, &linecap, stdin)) > 0) {
char * buf = NULL;
size_t size = 1000;
char * s = getcwd(buf, size);
printf("%s# ", s);
*(line+linelen-1) = '[=10=]';
chdir(&line[3]);
}
return 0;
}
我没有得到程序的输出,我在下面显示了这一点(首先,我需要按一次回车键来获得提示——这没关系,并且是为这个例子准备的)。
/path/to/dir# cd ..
/path/to/dir#
/path/to#
您的循环执行以下逻辑:
- 等待用户输入
- 打印当前目录
- 更改当前目录
因此每次输入用户输入时,它都会显示旧目录、更改目录(没有可见输出)然后等待新输入。这确实是您的示例输出显示的内容。
要获得您想要的行为,请移动 getcwd
并向下显示到 chdir
调用下方。
请注意,如果此人随后输入了一个短于 3 的字符串(例如,他们再次按下 Enter,我在测试时做了,你也是),你仍然会继续调用 chdir(&line[3]);
,导致意外结果(可能UB) 因为这已经过了字符串的末尾。在我的系统上它重复了 chdir("..")
。要解决此问题,您可能应该检查 linelen >= 3
(并且它确实以 cd
开头),如果不是,则不要调用 chdir
。