错误消息:转换可能会丢失有效数字

时间:2011-11-08 19:38:02

标签: c

C程序使用getchar()和putchar()函数接受并显示“5”字符:

#include<stdio.h>
void main()
{
  char ch[6];

  ch[0]=getchar();
  ch[1]=getchar();
  ch[2]=getchar();
  ch[3]=getchar();
  ch[4]=getchar();

  putchar(ch[0]);
  putchar(ch[1]);
  putchar(ch[2]);
  putchar(ch[3]);
  putchar(ch[4]);
}

当我用“C”语言编译此代码时,它显示此错误消息: “转换可能会失去有效数字”,原因可能是什么?

2 个答案:

答案 0 :(得分:5)

getchar会返回int,您将其存储在char中。

您可以将char ch[6];更改为int ch[6];

来解决此问题

答案 1 :(得分:2)

getchar()返回int,以允许传递不在有效字符范围内的其他值。这允许将失败和错误代码作为值返回,而不会使具有多个含义的特定字符超载。在正常操作中,可能会返回任何有效字符,在错误操作中,返回的int太大而无法放入char

警告消息表明您只会查看返回值的char部分,因此,您可能奇怪地将错误或特殊返回值转换为char。实际上已经捕获了。

---根据Gautham的要求编辑,以证明良好的错误检测---

缺少输入故障的错误检查可以通过两种方式之一进行修复。第一个更常见,适用于整数大小大于字符大小的所有系统。

  // an ok approach which works for most systems
  // provided that sizeof(int) != sizeof(char)
  int c = getchar();
  if (EOF != c) {
    ch[0] = (char)c;
  } else {
    // some error occurred during input capture
    // which resulted in getchar returning EOF
  }

输入失败的错误检查的第二个解决方案不依赖于大于字符大小的整数的大小。它适用于所有系统。

  // a better approach which works for all systems
  // even where sizeof(int) == sizeof(char)
  c = getchar();

  if (!feof(stdin) && !ferror(stdin)) {
    // even if c was EOF, we know it's a char value, not an error value
    ch[0] = c;
  } else {
    // c's value is EOF because of an error capturing the input, and
    // not because a char value equaling EOF was read.
  }

将所有内容整合在一起以重写程序

#include<stdio.h>
int main(int argc, char** argv)
{
  char ch[6];

  ch[0]=getchar();
  ch[1]=getchar();
  ch[2]=getchar();
  ch[3]=getchar();
  ch[4]=getchar();

  putchar(ch[0]);
  putchar(ch[1]);
  putchar(ch[2]);
  putchar(ch[3]);
  putchar(ch[4]);

  return 0;
}

或者如果你已经介绍过程序,那就是上面提到的更好的版本

#include<stdio.h>

char getInput() {
  int c = getchar();

  if (!feof(stdin) && !ferror(stdin)) {
    return (char)c;
  } else {
    exit(EXIT_FAILURE);
  }
}

int main(int argc, char** argv)
{
  char ch[6];

  ch[0]=getInput();
  ch[1]=getInput();
  ch[2]=getInput();
  ch[3]=getInput();
  ch[4]=getInput();

  putchar(ch[0]);
  putchar(ch[1]);
  putchar(ch[2]);
  putchar(ch[3]);
  putchar(ch[4]);

  return 0;
}

如果您已经学习了一些关于循环的知识,可以使用类似的循环重写

#include<stdio.h>

char getInput() {
  int c = getchar();

  if (!feof(stdin) && !ferror(stdin)) {
    return (char)c;
  } else {
    exit(EXIT_FAILURE);
  }
}

int main(int argc, char** argv)
{
  char ch[6];
  int index;

  for (index = 0; index < 5; index++) {
    ch[index] = getInput();
  }

  for (index = 0; index < 5; index++) {
    putchar(ch[index]);
  }

  return 0;
}

您可能需要添加其他检查,例如检查putchar是否因输出期间的错误而失败;但是,如果您没有其他方法来呈现错误(比如将其写入文件),那么添加此类检查只会增加代码的复杂性,而无法提供将错误传达给最终用户的方法。

错误检查是编写健壮程序的最重要的项目之一,但在大多数编程课程中,它的处理非常轻松(如果它完全被覆盖)。如果您没有对错误检查进行太多讨论,请自己帮忙并独立阅读<errno.h>。可以找到关于如何处理C中的错误的合适描述in the GNU pages disussing error handling.基本的“打印到stderr”错误处理程序可能看起来像

 // this defines errno
 #include <errno.h>
 // this defines perror
 #include <stdio.h>
 // this defines strerror
 #include <string.h>

 extern volatile int errno;

 void printError(int value) {
   perror(strerror(value));
 }