将输入从 getchar() 复制到另一个变量

Copying the input from `getchar()` to another variable

在 K&R 书中的以下代码示例中,如果我将 putchar(c) 替换为 printf("%c", c),则代码的工作原理相同。但是如果我用 printf("%d", c) 替换它,它会给出乱码输出。

#include <stdio.h>
int main() {
  int c;
  c = getchar();
  while (c != EOF) {
    putchar(c);
    c = getchar();
  }
}

了解到getchar()将stdin转换为8位字符,其值范围为0到255。

现在我想在一行中使用 putchar(c) 并在另一行中使用 printf("%d", c) 来打印 c 的值。所以我写了下面的代码:

#include <stdio.h>

int main() {
  int c, b;

  c = getchar();
  b = c;
  while (c != EOF && c != 10) {
    printf("%c",c);
    c = getchar();
  }
  printf("\n");
  while (b != EOF && b != 10) {
    printf("%d\t",b);
    b = getchar();
  }
}

我使用条件 c != 10 因为换行符被 getchar() 读取为 10。我希望代码能像

$ ./a.out
783
783
55 56 51

但程序终止为

$ ./a.out
783
783
55

我知道 getchar() 从标准输入获取输入,而变量 b 不是标准输入。那么我应该如何将变量 c 复制到 b 以便我的程序按预期运行?

问题是您的代码没有(并且不能,就目前而言)'remember' 您在第一个循环中提供的输入。因此,在您完成该循环之后,您的第二个循环想要读入 b 的字符(在它输出第一个值之后,该值从之前的 b = c 行中记住)。

所以,输出完55(字符7的整数),等待进一步输入。

可能获得所需输出的最简单方法是使用 数组 输入字符。然后,您可以在阅读时输出 %c 值(和以前一样),然后在随后的 for 循环中使用 %d 格式重新 运行 输出。

这是一个演示,可以满足您的需求:

#include <stdio.h>
#define MAXINS 20 // Set to the maximum number of input characters you want to allow
int main()
{
    int c[MAXINS];
    int i = 0, n = 0;
    c[0] = getchar();
    while (i < MAXINS && c[i] != EOF && c[i] != 10) {
        printf("%c", c[i]);
        c[++i] = getchar();
        ++n;
    }
    printf("\n");
    for (i = 0; i < n; ++i) {
        printf("%d\t", (int)(c[i]));
    }
    return 0;
}

随时要求进一步澄清and/or解释。

编辑:关于你第一段的观点,"But if I replace it with printf("%d", c) 它给出了乱码输出。" 好吧,当我尝试以下代码并给出 783 然后点击 return (生成换行符)时,我得到了预期的 55565110 作为输出:

int main()
{
    int c;
    c = getchar();
    while (c != EOF) {
        printf("%d", c);
        c = getchar();
    }
    return 0;
}

这可能看起来像乱码,但它与您在后面的代码中 'expect' 的输出相同,只是没有空格,并且添加了 10 作为换行符。

您只复制了第一个输入,要复制整个字符串,您需要将每个输入存储在缓冲区中,并检查字符串是否在每次迭代时都没有溢出该缓冲区:

int main(void)
{
    enum {size = 256};
    char buffer[size];
    size_t count = 0;
    int c;

    while ((c = getchar()) && (c != '\n') && (c != EOF))
    {
        printf("%c", c);
        if (count < size)
        {
            buffer[count++] = (char)c;
        }
    }
    printf("\n");
    for (size_t iter = 0; iter < count; iter++)
    {
        printf("%d\t", buffer[iter]);
    }
    printf("\n");
}

如果您不想将缓冲区限制为任意大小,那么您需要更改使用动态内存的方法(realloc 或链表)

您需要存储每个字符,因为一旦您从 stdin 读取 char,它就不再出现在 stdin 中。

既然你要最后的换行符作为输入的一部分,你应该使用fgets来取输入。

假设您正在接受最多 100 个字符的输入。

#include <stdio.h>

int main(void) {
    char c[100]; // A char array
    fgets(c,100,stdin);
    int x=0;
    while (c[x] != 10 && c[x] != EOF)
        printf("%c",c[x++]);
    printf("\n");
    x = 0;
    while (c[x] != 10 && c[x] != EOF) // You can simply compare it with the newline character too.
        printf("%d ",c[x++]);
    printf("\n");
    return 0;
}

有很多方法可以做到这一点。您还可以逐个字符读取 stdin 并将其存储在数组中。但是,由于显示字符本身后需要在另一行显示字符的ASCII值,因此必须将它们存储在数组中。