我写了一个程序来解决K& R的练习2-2。
#include<stdio.h>
#define MAXLINE 1000
/* write an equivalent loop without using && or || */
int Getline(char s[], int lim);
int main()
{
int len;
char line[MAXLINE];
while ((len = Getline(line, MAXLINE)) > 0) {
printf("%s%15s%d\n", line, "length: ", len);
}
return 0;
}
int Getline(char s[], int lim)
{
int flag = 1;
int i = 0, c = 0;
for (i = 0; flag == 1; ++i) {
if (i < lim - 1) {
if ((c = getchar()) != '\n') {
if (c != EOF) {
;
}
else {
flag = 0;
}
}
else {
flag = 0;
}
}
else {
flag = 0;
}
if (flag == 1) {
s[i] = c;
}
}
if (c == '\n') {
s[i] = c;
++i;
}
s[i] = '\0';
return i;
}
这个程序错了......以一种奇怪的方式。 我使用重定向运行此代码,如
./2-2 <in
文件中的
获取此行。
然后输出到屏幕是无数的
G长度:1
看起来程序陷入了循环。但是当我停止使用重定向并只输入获取此行。到终端时,虽然它仍然是错误的,但无数输出消失了。为什么呢?
答案 0 :(得分:1)
问题在于:
for (i = 0; flag == 1; ++i) {
^^^
i will always increment to at least 1
before the for-loop ends
so your function will never return 0
不是在for循环中递增,而是在插入新元素后才增加。像
if (flag == 1) {
s[i] = c;
++i;
}
您可以使用while循环代替for循环,例如:
int i = 0;
while (flag == 1)
{
...
}
下一步是摆脱旗帜并使用break
insted。像:
int i = 0;
while (1)
{
if (i >= lim - 1) break;
...
}
您的代码将更短,更易于阅读。
答案 1 :(得分:1)
你的功能也很复杂了。如果您只想从文件中重定向该行,请将其存储在line
中,并确保它 nul-terminated (并且没有尾随'\n'
- 您不应该这样做'你可以做一些非常简单的事情:
int Getline (char *s, int lim)
{
int i = 0; /* char count - length */
while (i < lim - 1) { /* loop while chars fit */
int c = getchar(); /* getchar */
if (c == EOF) /* validate EOF? */
goto done;
if (c == '\n') /* validate newline */
continue;
s[i++] = c; /* good char, increment len */
}
done:;
s[i] = 0; /* nul-terminate */
return i; /* return length */
}
(注意:来自您之前未使用break
的评论,然后一个简单的goto
同样有用)
示例使用/输出
鉴于您的文件包含第"Get this line."
行
$ ./bin/equivloop <dat/in
Get this line. length: 14
(注意:如果存储换行符,则长度为15,输出将在下一行)