简体   繁体   English

从文件向未签名的char变量赋值的奇怪行为

[英]Strange behaviour assigning value from file to unsigned char variable

I have been looking for an error in a code that I am using for finite element methods. 我一直在寻找用于有限元方法的代码中的错误。 The point is that I have to get some data from a file to identify the material of a cell. 关键是我必须从文件中获取一些数据以标识单元格的材料。 The type of this material_id is unsigned char , and here is the problem. 这个material_id的类型是unsigned char ,这就是问题所在。

When reading the data from the file, different ways to assign the value to a unsigned char variable gives different result. 从文件读取数据时,将值分配给无符号char变量的不同方法会产生不同的结果。 I have fixed the problem, but I am still wondering why it is working in a different way. 我已经解决了问题,但是我仍然想知道为什么它以不同的方式起作用。 Here you have a sample code reproducing the different behavior: 在这里,您有一个示例代码再现了不同的行为:

#include <map>
#include <sstream>
#include <fstream>
#include <string>
#include <iostream>
#include <vector>
#include <stdlib.h>

namespace types
{
//typedef unsigned int material_id;
typedef unsigned char  material_id;
}

namespace Utilities
{
  int string_to_int(const std::string & str)
  {
    return atoi(str.c_str());
  }
}

template<typename Number>
void parseVector_1(std::ifstream & myfile,
                   std::vector<Number> & mat_id)
{
  Number num;
  std::string line, bin;

  if (myfile.is_open())
  {
    getline (myfile,line);
    std::istringstream iss(line);
    while ( iss.good() )
    {
      iss >> bin;                            // option 1
      num = Utilities::string_to_int(bin);   // option 1
      mat_id.push_back(num);
    }
  }
  else std::cout << "Unable to open file"; 
}

template<typename Number>
void parseVector_2(std::ifstream & myfile,
                   std::vector<Number> & mat_id)
{
  Number num;
  std::string line, bin;

  if (myfile.is_open())
  {
    getline (myfile,line);
    std::istringstream iss(line);
    while ( iss.good() )
    {
      iss >> num; // option 2
      mat_id.push_back(num);
    }
  }
  else std::cout << "Unable to open file"; 
}

int main()
{
  unsigned int n_mat;

  std::vector<types::material_id> mat_id_1;
  std::vector<types::material_id> mat_id_2;
  std::map<types::material_id, double> D1v;

  D1v[0] = 0.0;
  D1v[1] = 1.0;
  D1v[2] = 2.0;
  D1v[3] = 3.0;
  D1v[4] = 4.0;

  std::ifstream myfile1 ("materials.dat");
  parseVector_1(myfile1, mat_id_1);
  myfile1.close();


  std::ifstream myfile2 ("materials.dat");
  parseVector_2(myfile2, mat_id_2);
  myfile2.close();

  n_mat = mat_id_1.size();
  std::cout << "option 1: ";
  for (unsigned int i = 0; i < n_mat; ++i)
    std::cout << "mat["<<i<<"]=" << D1v[mat_id_1[i]] << " ";
  std::cout << std::endl;

  n_mat = mat_id_2.size();
  std::cout << "option 2: ";
  for (unsigned int i = 0; i < n_mat; ++i)
    std::cout << "mat["<<i<<"]=" << D1v[mat_id_2[i]] << " ";
  std::cout << std::endl;

  return 0;

}

The content of the "materials.dat" file is the following line: “ materials.dat”文件的内容是以下行:

0 1 2 3 4 0 1 2 3 4

And here is the output of the execution: 这是执行的输出:

$ unsignedchar_problem.exe 
option 1: mat[0]=0 mat[1]=1 mat[2]=2 mat[3]=3 mat[4]=4  
option 2: mat[0]=0 mat[1]=0 mat[2]=0 mat[3]=0 mat[4]=0 mat[5]=0

Can anyone give some insight why option 1 is working fine, but option 2 is not? 谁能说出为什么选项1可以正常工作,而选项2却不能正常工作? Is it dependent on the compiler/platform of it is always like that? 它总是依赖于它的编译器/平台吗?

As an additional information, the problem was because the material_id type was defined as unsigned int by the other user in his computer, so it was working without any problem. 作为附加信息,问题是因为material_id类型被他的计算机中的另一个用户定义为unsigned int ,所以它可以正常工作。

Extracting unsigned char from an istream reads a single character and stores that character's numeric value into the destination variable. 从istream中提取unsigned char将读取单个字符,并将该字符的数值存储到目标变量中。 So mat_id_2[0] will contain the numeric value of '0' , which is probably 48 (if your system is ASCII). 因此mat_id_2[0]将包含数字值'0' ,该值可能是48(如果您的系统是ASCII)。

Extracting a non-chararacter integral type will read an integer and store the value of that integer, as you were expecting. 如您所料,提取非字符整数类型将读取一个整数并存储该整数的值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM