【问题标题】:K&R Exercise 1-19 unexpected and inconsistent outputK&R 练习 1-19 意外和不一致的输出
【发布时间】:2016-02-24 23:52:11
【问题描述】:

一直在进行 K&R 练习 1-19:

编写一个程序,一次将其输入反转一行。

编写了以下程序:

#include <stdio.h>
#define MAXLINE 1000

main () {
    int c, x, y, z;
    char ip[MAXLINE];
    char ln[MAXLINE];
    char rv[MAXLINE];

    for (x = 0;(c=getchar()) != EOF; ++x)       
        ip[x] = c;

    for (x = 0; ip[x] != '\0'; ++x) {               
        for (y = 0; ip[x] != '\n'; ++y) {           
            ln[y] = ip[x];
            ++x;
        }

        for (z = 0; y != -1; ++z) {                 
            rv[z] = ln[y];
            --y;
        }
        printf("%s\n", rv);                         
    }
}

我的问题是这个程序的输出非常不一致;给定相同的(多行)输入,有时它会反向打印每一行并添加前导空格,有时它只会反向复制第一行,然后是空白行,有时它会打印垃圾,有时我只是得到一个错误信息。

之前有没有人在不更改代码的情况下遇到过这种波动?我该如何解决?

【问题讨论】:

  • 你上次发了很多相关的问题。请考虑使用不同的(和更新的 - 自 K&R 上次更新以来 C 已经发展了很多)书籍和/或教程。堆栈溢出不是一个教程网站。
  • 考虑到这一点,在您的第二个循环中,您测试ip 中的空字符。你在读的时候设置了空字符吗?
  • 您正在将整个输入读入一个 1000 字节的缓冲区,而不检查输入是否超过 1000 字节。您没有'\0' 终止ip 字符串,但x 循环查找ip[x] != '\0'。而且您没有在rv 字符串的末尾添加'\0',这意味着printf 将超出字符串的末尾。
  • 强烈建议一次只读取一行来处理。这意味着第一个 for() 循环还需要检查 \n 以找到行尾。并且同样的循环需要检查行中的字符数,以便输入缓冲区不会溢出。
  • 在 C 中,main() 只有极少数有效签名,它们都有返回类型,并且(除非在没有操作系统的裸机上工作,否则返回类型将为 int

标签: c runtime-error garbage kernighan-and-ritchie


【解决方案1】:

如果你在做 K&R,我建议你购买“C 答案书”,它包含所有练习的答案。

试试这个:

#include <stdio.h>

#define MAX_LINE 1024

void discardnewline(char s[])
{
  int i;
  for(i = 0; s[i] != '\0'; i++)
  {
    if(s[i] == '\n')
      s[i] = '\0';
  }
}

int reverse(char s[])
{
  char ch;
  int i, j;

  for(j = 0; s[j] != '\0'; j++)
  {
  }

  --j;

  for(i = 0; i < j; i++)
  {
    ch   = s[i];
    s[i] = s[j];
    s[j] = ch;
    --j;
  }

  return 0;
}

int getline(char s[], int lim)
{
  int c, i;

  for(i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; ++i)
  {
    s[i] = c;
  }

  if(c == '\n')
  {
    s[i++] = c;
  }

  s[i] = '\0';

  return i;

}

int main(void)
{
  char line[MAX_LINE];

  while(getline(line, sizeof line) > 0)
  {
    discardnewline(line);
    reverse(line);
    printf("%s\n", line);
  }
  return 0;
}

部分内容来自书中,但我什至做了自己的修改。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-25
    • 1970-01-01
    相关资源
    最近更新 更多