【问题标题】:Indexing doesn't work in two nested loops索引在两个嵌套循环中不起作用
【发布时间】:2016-06-18 12:25:39
【问题描述】:

我已经使用 Python 编码大约一年了,并决定也学习 C。我试图编写一个函数来逐行反转给定的字符数组(来自 K&R 的练习)。代码如下:

void reverse(char s[]) {
    int i, lastIndex, tempLetter1, tempLetter2;
    i = lastIndex = 0;
    while (s[lastIndex] != EOF) {
        while (s[lastIndex] != '\n') {
            i = lastIndex;
            tempLetter2 = s[i];
            while (s[i] != '\n') {
                tempLetter1 = tempLetter2;
                tempLetter2 = s[i + 1];
                s[i + 1] = tempLetter1;
                ++i;
            }
            ++lastIndex;
        }
        ++lastIndex;
    }
}

这以无限循环结束。我在第二个循环中插入了一些打印代码:

printf("s[0] = ");
putchar(s[0]);
printf("\ns[1] = ");
putchar(s[1]);
printf("\ns[2] = ");
putchar(s[2]);

它们都包含输入数组的第一个字符 (Hello World)。

s[0] = H
s[1] = H
s[2] = H

我也省略了第一个 while 循环,但仍然没有工作。尽管索引在循环外工作正常。第三个循环也有效。

我已经放了整个代码,以防它的其他方面写得不好,如果指出我将不胜感激:)

#include <stdio.h>
#define LEN 1000

void getLine(char[]);
void reverse(char[]);

int main() {
    char line[LEN];
    getLine(line);
    reverse(line);
    printf("\n%s\n", line);
    return 0;
}

void getLine(char s[]) {
    int i, c;
    for (i = 0; (c = getchar()) != EOF; ++i) {
        s[i] = c;
    }
    s[i] = '\0';
}

【问题讨论】:

  • 您的代码中存在严重的逻辑错误。请检查。此外,char 数组以 '\0' 而不是 '\n' 结尾。
  • @denis 感谢您的回复。你能再解释一下吗?我也在检查'\n' 的新行。也许我应该用'\0' 替换EOF
  • 如何定义和初始化传入reverse()的内容?
  • 我在main()void reverse(char[]) 之前对其进行了原型设计。我还定义了一个函数getLine(char s[], int len),它使用getchar() 用输入字符填充给定的数组。然后我用reverse(s)调用函数。
  • 遵循以下逻辑:for (i = 0; (c = getchar()) != EOF; ++i) EOF 存储在数组 line 中。所以在reverse() 中测试它是没有用的。 getline() 使用s[i] = '\0'; 放置一个尾随'\0' 作为字符串结束标记,即0-终止符,以使char-array line 成为C-“字符串”。

标签: c arrays indexing c-strings


【解决方案1】:

您的代码以

开头
while (s[lastIndex] != EOF) {

鉴于此处没有进行文件读取,EOF(文件结尾)不正确。你的意思是0,意思是字符串的结尾吗?或者更好的是,'\0' 表示字符形式的字符串结尾? (也称为NUL,但未定义该符号。)

好吧,假设s的第一个字符不是EOF,那么它立即进入第二个循环:

while (s[lastIndex] != '\n') {

第一件事:不再检查NUL。如果你点击NUL,它会直接从它身边闪过……但假设输入字符串格式正确,并且它在最后一个NUL 之前的最后一个字符是'\n',让我们继续。

据我了解,您希望反转主字符串中每一行的字符。这意味着您需要记住行首(很好,那是在lastIndex - 可惜名字),然后去寻找行尾。您正在为此使用i...

等一下:你正在交换字符吗?当然,您应该寻找行尾,然后开始移动lastIndexi 彼此越来越近,边走边换?所以你应该在同一循环内增加lastIndex递减 i

还是我错过了什么?

【讨论】:

  • 谢谢约翰,我同意,算法可能需要一些工作......虽然让我困惑的是第二个循环中的s[0]s[2] 是相同的!我还删除了第一个循环(检查EOF - 应该检查'\0'),问题仍然存在。
  • 如果您正在摆弄我们原始帖子中给出的循环,我不明白您说“反向”时要做什么。给出的代码会将“ABCDE”变成“AABCD”——你永远不会分配给s[i]
  • 再次感谢,我在第三次循环后错过了s[lastIndex] = tempLetter2。我把它放进去工作了......虽然我仍然不明白为什么各种索引返回相同的值(在第三个循环之前和之后)......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-02
相关资源
最近更新 更多