简体   繁体   English

如何存储在字符串中并转换为字符数组?

[英]How to store in a string and convert to character array?

Write a C++ program to perform addition of two hexadecimal numerals which are less than 100 digits long. 编写一个C ++程序来执行两个小于100位数字的十六进制数字的加法运算。 Use arrays to store hexadecimal numerals as arrays of characters.the solution is to add the corresponding digits in the format of hexadecimal directly. 使用数组将十六进制数字存储为字符数组。解决方案是直接以十六进制格式添加相应的数字。 From right to left, add one to the digit on the left if the sum of the current digits exceed 16. You should be able to handle the case when two numbers have different digits. 如果当前数字的总和超过16,请从右到左在左边的数字上加一个。如果两个数字具有不同的数字,则应该能够处理这种情况。

The correct way to get the input is to store as character array. 获取输入的正确方法是将其存储为字符数组。 You can either first store in a string and convert to character array, or you can use methods such as cin.getline(), getc() , cin.get() to read in the characters. 您可以先存储在字符串中并转换为字符数组,也可以使用诸如cin.getline(), getc()cin.get()方法读取字符。

I don't know what is wrong with my program and it I don't know how to use the function getline() and eof() 我不知道我的程序出了什么问题,也不知道如何使用函数getline()eof()

 char a[number1],b[number1],c[number2],h;
int m,n,p(0),q(0),k,d[number1],z[number1],s[number2],L,M;
cout<<"Input two hexadecimal numerals(both of them within 100 digits):\n";
cin.getline(a,100);
cin.getline(b,100);
int x=strlen(a) ;
int y=strlen(b);
for(int i=0;i<(x/2);i++)
    {
      m=x-1-i;
      h=a[i];
      a[i]=a[m];
      a[m]=h;
    }
for(int j=0;j<(y/2);j++)
    {
      n=y-1-j;
      h=b[j];
      b[j]=b[n];
      b[n]=h;
    }
if(x>y)
{
    for(int o=0;o<x;o++)//calculate a add b
    {
        if(o>=(y-1))
            z[o]=0;//let array b(with no character)=0
        if(a[o]=='A')
        d[o]=10;
        else if(a[o]=='B')
        d[o]=11;
        else if(a[o]=='C')
        d[o]=12;
        else if(a[o]=='D')
        d[o]=13;
        else if(a[o]=='E')
        d[o]=14;
        else if(a[o]=='F')
        d[o]=15;
        else if(a[o]=='0')
        d[o]=0;
        else if(a[o]=='1')
        d[o]=1;
        else if(a[o]=='2')
        d[o]=2;
        else if(a[o]=='3')
        d[o]=3;
        else if(a[o]=='4')
        d[o]=4;
        else if(a[o]=='5')
        d[o]=5;
        else if(a[o]=='6')
        d[o]=6;
        else if(a[o]=='7')
        d[o]=7;
        else if(a[o]=='8')
        d[o]=8;
        else if(a[o]=='9')
        d[o]=9;
        if(b[o]=='A')
        z[o]=10;
        else if(b[o]=='B')
        z[o]=11;
        else if(b[o]=='C')
        z[o]=12;
        else if(b[o]=='D')
        z[o]=13;
        else if(b[o]=='E')
        z[o]=14;
        else if(b[o]=='F')
        z[o]=15;
        else if(b[o]=='0')
        z[o]=0;
        else if(b[o]=='1')
        z[o]=1;
        else if(b[o]=='2')
        z[o]=2;
        else if(b[o]=='3')
        z[o]=3;
        else if(b[o]=='4')
        z[o]=4;
        else if(b[o]=='5')
        z[o]=5;
        else if(b[o]=='6')
        z[o]=6;
        else if(b[o]=='7')
        z[o]=7;
        else if(b[o]=='8')
        z[o]=8;
        else if(b[o]=='9')
        z[o]=9;
        p=d[o]+z[o]+q;
        if(p>=16)//p is the remained number
        {
           q=1;
           p=p%16;
        }
        else
            q=0;

        if(p==0)
        c[o]='0';
        else if(p==1)
        c[o]='1';
        else if(p==2)
        c[o]='2';
        else if(p==3)
        c[o]='3';
        else if(p==4)
        c[o]='4';
        else if(p==5)
        c[o]='5';
        else if(p==6)
        c[o]='6';
        else if(p==7)
        c[o]='7';
        else if(p==8)
        c[o]='8';
        else if(p==9)
        c[o]='9';
        else if(p==10)
        c[o]='A';
        else if(p==11)
        c[o]='B';
        else if(p==12)
        c[o]='C';
        else if(p==13)
        c[o]='D';
        else if(p==14)
        c[o]='E';
        else if(p==15)
        c[o]='F';

    }
k=x+1;
if(q==1)//calculate c[k]
   {
    c[k]='1';
    for(int f=0;f<=(k/2);f++)
    {
      m=k-f;
      h=c[f];
      c[f]=c[m];
      c[m]=h;
    }
   }
else
   {
      for(int e=0;e<=(x/2);e++)
    {
      m=x-e;
      h=c[e];
      c[e]=c[m];
      c[m]=h;
    }
   }
}
if(x=y)
{
    for(int o=0;o<x;o++)//calculate a add b
    {
        if(a[o]=='A')
        d[o]=10;
        else if(a[o]=='B')
        d[o]=11;
        else if(a[o]=='C')
        d[o]=12;
        else if(a[o]=='D')
        d[o]=13;
        else if(a[o]=='E')
        d[o]=14;
        else if(a[o]=='F')
        d[o]=15;
        else if(a[o]=='0')
        d[o]=0;
        else if(a[o]=='1')
        d[o]=1;
        else if(a[o]=='2')
        d[o]=2;
        else if(a[o]=='3')
        d[o]=3;
        else if(a[o]=='4')
        d[o]=4;
        else if(a[o]=='5')
        d[o]=5;
        else if(a[o]=='6')
        d[o]=6;
        else if(a[o]=='7')
        d[o]=7;
        else if(a[o]=='8')
        d[o]=8;
        else if(a[o]=='9')
        d[o]=9;
        if(b[o]=='A')
        z[o]=10;
        else if(b[o]=='B')
        z[o]=11;
        else if(b[o]=='C')
        z[o]=12;
        else if(b[o]=='D')
        z[o]=13;
        else if(b[o]=='E')
        z[o]=14;
        else if(b[o]=='F')
        z[o]=15;
        else if(b[o]=='0')
        z[o]=0;
        else if(b[o]=='1')
        z[o]=1;
        else if(b[o]=='2')
        z[o]=2;
        else if(b[o]=='3')
        z[o]=3;
        else if(b[o]=='4')
        z[o]=4;
        else if(b[o]=='5')
        z[o]=5;
        else if(b[o]=='6')
        z[o]=6;
        else if(b[o]=='7')
        z[o]=7;
        else if(b[o]=='8')
        z[o]=8;
        else if(b[o]=='9')
        z[o]=9;
        p=d[o]+z[o]+q;
        M=p;
        if(p>=16)
        {
           q=1;
           p=p%16;
        }
        else
            q=0;
        s[o]=p;
        if(p==0)
        c[o]='0';
        else if(p==1)
        c[o]='1';
        else if(p==2)
        c[o]='2';
        else if(p==3)
        c[o]='3';
        else if(p==4)
        c[o]='4';
        else if(p==5)
        c[o]='5';
        else if(p==6)
        c[o]='6';
        else if(p==7)
        c[o]='7';
        else if(p==8)
        c[o]='8';
        else if(p==9)
        c[o]='9';
        else if(p==10)
        c[o]='A';
        else if(p==11)
        c[o]='B';
        else if(p==12)
        c[o]='C';
        else if(p==13)
        c[o]='D';
        else if(p==14)
        c[o]='E';
        else if(p==15)
        c[o]='F';

    }
k=x+1;
if(q==1)
   {
    c[k]='1';
    for(int f=0;f<=(k/2);f++)
    {
      m=k-f;
      h=c[f];
      c[f]=c[m];
      c[m]=h;
    }
   }
else
   {
      for(int e=0;e<=(x/2);e++)
    {
      m=x-e;
      h=c[e];
      c[e]=c[m];
      c[m]=h;
    }
   }
}

Lets look at what cin.getline does: 让我们看看cin.getline作用:

Extracts characters from stream until end of line. 从流中提取字符,直到行尾。 After constructing and checking the sentry object, extracts characters from *this and stores them in successive locations of the array whose first element is pointed to by s, until any of the following occurs (tested in the order shown): 在构造并检查了哨兵对象之后,从* this中提取字符并将它们存储在数组的连续位置,该数组的第一个元素由s指向,直到发生以下任何一种情况(按所示顺序进行测试):

  • end of file condition occurs in the input sequence (in which case setstate(eofbit) is executed) 文件结束条件发生在输入序列中(在这种情况下,将执行setstate(eofbit))
  • the next available character c is the delimiter, as determined by Traits::eq(c, delim). 下一个可用字符c是定界符,由Traits :: eq(c,delim)确定。 The delimiter is extracted (unlike basic_istream::get()) and counted towards gcount(), but is not stored. 分隔符被提取(与basic_istream :: get()不同)并计入gcount(),但不存储。
  • count-1 characters have been extracted (in which case setstate(failbit) is executed). 已提取count-1个字符(在这种情况下,将执行setstate(failbit))。

If the function extracts no characters (eg if count < 1), setstate(failbit) is executed. 如果函数未提取任何字符(例如,如果count <1),则执行setstate(failbit)。 In any case, if count>0, it then stores a null character CharT() into the next successive location of the array and updates gcount(). 无论如何,如果count> 0,则它将空字符CharT()存储到数组的下一个连续位置,并更新gcount()。

The result of that is in all cases, s now points to a null terminated string, of at most count-1 characters. 结果是在所有情况下s现在都指向一个空的终止字符串,最多为count-1字符。

In your usage, you have up to 99 digits, and can use strlen to count exactly how many. 在使用中,您最多可以使用99位数字,并且可以使用strlen精确地计算出多少位数。 eof is not a character, nor it is a member function of char . eof不是字符,也不是char的成员函数。

You then reverse in place the inputs, and go about your overly repetitious conversions. 然后,您将输入取反,然后进行过度重复的转换。

However, it's much simpler to use functions, both those you write yourself and those provided by the standard. 但是,使用函数(无论是您自己编写的函数还是标准提供的函数)要简单得多。

// translate from '0' - '9', 'A' - 'F', 'a' - 'f' to 0 - 15
static std::map<char, int> hexToDec { { '0', 0 }, { '1', 1 }, ... { 'f', 15 }, { 'F', 15 } };
// translate from 0 - 15 to '0' - '9', 'A' - 'F'
static std::map<int, char> decToHex { { 0, '0' }, { 1, '1' }, ... { 15, 'F' } };

std::pair<char, bool> hex_add(char left, char right, bool carry)
{
    // translate each hex "digit" and add them
    int sum = hexToDec[left] + hexToDec[right];
    // we have a carry from the previous sum
    if (carry) { ++sum; }
    // translate back to hex, and check if carry
    return std::make_pair(decToHex[sum % 16], sum >= 16);
}

int main()
{
    std::cout << "Input two hexadecimal numerals(both of them within 100 digits):\n";
    // read two strings
    std::string first, second;
    std::cin >> first >> second;

    // reserve enough for final carry
    std::string reverse_result(std::max(first.size(), second.size()) + 1, '\0'); 

    // traverse the strings in reverse
    std::string::const_reverse_iterator fit = first.rbegin();
    std::string::const_reverse_iterator sit = second.rbegin();
    std::string::iterator rit = reverse_result.begin();
    bool carry = false;

    // while there are letters in both inputs, add (with carry) from both
    for (; (fit != first.rend()) && (sit != second.rend()); ++fit, ++sit, ++rit)
    {
        std::tie(*rit, carry) = hex_add(*fit, *sit, carry);
    }

    // now add the remaining digits of first (will do nothing if second is longer)
    for (; (fit != first.rend()); ++fit)
    {
        // we need to account for a carry in the last place 
        // potentially all the way up if we are adding e.g. "FFFF" to "1"
        std::tie(*rit, carry) = hex_add(*fit, *rit++, carry);
    }
    // or add the remaining digits of second
    for (; (sit != second.rend()); ++sit)
    {
        // we need to account for a carry in the last place 
        // potentially all the way up if we are adding e.g. "FFFF" to "1"
        std::tie(*rit, carry) = hex_add(*sit, *rit++, carry);
    }

    // result has been assembled in reverse, so output it reversed
    std::cout << reverse_result.reverse();
}

This is a long answer. 这是一个很长的答案。 Because you have much bug in your code. 因为您的代码中有很多错误。 Your using of getline is ok. 您可以使用getline。 But your are calling a eof() like e.eof() which is wrong. 但是您正在调用e.eof()类的eof e.eof() ,这是错误的。 If you have looked at your compilation error, you would see that it was complaining about calling eof() on the variable e because it is of non-class type. 如果查看编译错误,您会发现它抱怨在变量e上调用eof(),因为它是非类类型的。 Simple meaning it is not an object of some class. 简单的意思是它不是某个类的对象。 You cannot put the dot operator . 您不能放置点运算符. on primitive types like that. 像这样的原始类型。 I think what you are wanting to do, is to terminate the loop when you have reached the end of line. 我认为您想要做的是在到达行尾时终止循环。 So that index1 and index2 can get the length of the string input. 这样index1和index2可以获取字符串输入的长度。 If I were you, I would just use C++ builtin strlen() function for that. 如果我是你,我只会使用C ++内置的strlen()函数。 And in the first place, you should use C++ class string to handle strings. 首先,您应该使用C ++类string来处理字符串。 Also strings have a null - terminating character '\\0' at the end of them. 另外,字符串的结尾为空-终止字符'\\ 0'。 If you don't know about it, I suggest you take some time to read about strings. 如果您不了解它,我建议您花一些时间来阅读有关字符串的信息。

Secondly, you have many bugs and errors in your code. 其次,您的代码中存在许多错误和错误。 The way you are reversing your string is not correct. 反转字符串的方式不正确。 Ask yourself, what are the contents of the arrays a and b at position which have higher index than the length of the string? 问问自己,索引a比字符串的长度高的数组ab的内容是什么? You should use reverse() for reversing strings and arrays. 您应该使用reverse()反转字符串和数组。

You have errors on adding loop also. 您在添加循环时也有错误。 Note, you are changing the arrays value when they are A , B , C , D , and so on for hexadecimal values with the corresponding decimal values 10,11,12,13 and so on. 请注意,对于十六进制值的数组值ABCD等等,您将更改它们的值,以及对应的十进制值10、11、12、13等。 But you should change the values for the character '0' - '9' also. 但是您也应该更改字符“ 0”-“ 9”的值。 Because when the array holds '0' it is not integer 0. But is is ASCII '0' which has integer value of 48. And the character '1' has integer value of 49 and so on. 因为当数组保留'0'时,它不是整数0。而是ASCII'0',其整数值为48。字符'1'的整数值为49,依此类推。 You want to replace this values with corresponding integer values also. 您还想用相应的整数值替换此值。 When you are also storing the result values in c , you are only handling only those values which are above 9 and replacing them with corresponding characters. 当您还将结果值存储在c ,您将仅处理那些大于9的值,并用相应的字符替换它们。 You should also replace the integers 0 - 9 with there corresponding ASCII characters. 您还应该用相应的ASCII字符替换整数0-9。 Also don't forget to put a null terminating character at the end of the result. 同样不要忘记在结果的末尾添加一个空终止符。

Also, when p is getting larger than 15, you are only changing your carry, but you should also change p accordingly. 同样,当p变得大于15时,您只是在更改进位,但也应相应地更改p

I believe you can reverse the result array c in a much more elegant way. 我相信您可以以更优雅的方式反转结果数组c By only reversing when the calculation has been performed totally. 仅在完全执行计算后才反转。 You can simple call reverse() for that. 您可以为此简单地调用reverse()

I believe you can think hard a little bit more, and write the code in the right way. 我相信您可以再努力一点,并以正确的方式编写代码。 I have a few suggestions for you, don't use variable names like a,b,c,o. 我为您提供一些建议,请勿使用变量名,例如a,b,c,o。 Try to name variables with what are they really doing. 尝试用变量的实际作用来命名变量。 Also, you can improve your algorithm and shorten your code and headache with one simple change in the algorithm. 而且,您可以通过对算法进行一次简单的更改来改进算法,并缩短代码和头痛的时间。 First find the length of a and then find the length of b . 首先找到的长度a ,然后找到的长度b If there lengths are unequal, find out which has lesser length. 如果长度不相等,请找出长度较小的长度。 Then add 0s in front of it to make both lengths equal. 然后在其前面加上0以使两个长度相等。 Now, you can simply start from the back, and perform the addition. 现在,您只需从背面开始,然后执行添加。 Also, you should use builtin methods like reverse() , swap() and also string class to make your life easier ;) 另外,您应该使用诸如reverse()swap()string类之类的内置方法,以使您的生活更轻松;)

#include <iostream>
#include <algorithm>
#include <string>
using namespace std;



int main(){
    string firstVal,secondVal;

    cout<<"Input two hexadecimal numerals(both of them within 100 digits):\n";

    cin >> firstVal >> secondVal;

    //Adjust the length.

    if(firstVal.size() < secondVal.size()){
        //Find out the number of leading zeroes needed
        int leading_zeroes = secondVal.size() - firstVal.size();

        for(int i = 0; i < leading_zeroes; i++){
            firstVal = '0' + firstVal;
        }
    }
    else if(firstVal.size() > secondVal.size()){
        int leading_zeroes = firstVal.size() - secondVal.size();

        for(int i = 0; i < leading_zeroes; i++){
            secondVal = '0' + secondVal;
        }
    }

    // Now, perform addition.
    string result;

    int digit_a,digit_b,carry=0;

    for(int i = firstVal.size()-1; i >= 0; i--){

        if(firstVal[i] >= '0' && firstVal[i] <= '9')  digit_a = firstVal[i] - '0';
        else                                          digit_a = firstVal[i] - 'A' + 10;

        if(secondVal[i] >= '0' && secondVal[i] <= '9')  digit_b = secondVal[i] - '0';
        else                                            digit_b = secondVal[i] - 'A' + 10;


        int sum = digit_a + digit_b + carry;
        if(sum > 15){
            carry = 1;
            sum = sum % 16;

        }
        else{
            carry = 0;
        }

        // Convert sum to char.
        char char_sum;
        if(sum >= 0 && sum <= 9)    char_sum = sum + '0';
        else                        char_sum = sum - 10 + 'A';

        //Append to result.
        result = result + char_sum;

    }
    if(carry > 0)   result = result + (char)(carry + '0');

    //Result is in reverse order.
    reverse(result.begin(),result.end());

    cout << result << endl;

}

Regarding the text of your problem: “add one to the digit on the left if the sum of the current digits exceed 16” is wrong; 关于您的问题的文本“如果当前数字的总和超过16,则在左边的数字上加一个”是错误的; it should be 15, not 16. 应该是15,而不是16。

Regarding your code : I did not have the patience to read all your code, however: 关于您的代码 :但是,我没有耐心阅读您的所有代码:

  • I have noticed one long if/else . 我注意到一个很长的if/else Use a switch (but you do not need one). 使用switch (但您不需要)。
  • To find out if a character is a hex digit use isxdigit ( #include <cctype> ). 要确定字符是否为十六进制数字,请使用isxdigit#include <cctype> )。
  • The user might input uppercase and lowercase characters: convert them to the same case using toupper / tolower . 用户可以输入大写和小写字符:使用toupper / tolower将它们转换为相同大小写。
  • To convert a hex digit to an integer: 要将十六进制数字转换为整数:
    • if the digit is between '0' and '9' simply subtract '0'. 如果数字在“ 0”和“ 9”之间,则只需减去“ 0”即可。 This works because the codes for '0', '1'… are 0x30, 0x31... (google ASCII codes). 之所以有效,是因为“ 0”,“ 1”…的代码分别为0x30、0x31 ...(Google ASCII代码)。
    • if the digit is between 'A' and 'F', subtract 'A' and add 10. 如果数字介于“ A”和“ F”之间,请减去“ A”并加10。

Solving the problem : 解决问题

  • “less than 100 digits long” This is a clear indication regarding how your data must be stored: a simple 100 long array, no std::string , no std::vector : “少于100位数字长”这是有关如何存储数据的明确指示:一个简单的100长数组,没有std::string ,没有std::vector

     #define MAX_DIGITS 100 typedef int long_hex_t[MAX_DIGITS]; 

    In other words your numbers are 100 digits wide, at most. 换句话说,您的电话号码最多不能超过100位数。

    Decide how you store the number: least significant digit first or last? 确定数字的存储方式:最低有效数字的第一个或最后一个? I would chose to store the least significant first. 我会选择先存储最低有效位。 123 is stored as {3,2,1,0,…0} 123被存储为{3,2,1,0,…0}

  • Use functions to simplify your code. 使用函数简化您的代码。 You will need three functions: read , print and add : 您将需要三个功能: readprintadd

     int main() { long_hex_t a; read( a ); long_hex_t b; read( b ); long_hex_t c; add( c, a, b ); print( c ); return 0; } 
  • The easiest function to write is add followed by print and read . 最简单的写入功能是add然后是printread

  • For read use get and putback to analyze the input stream: get extracts the next character from stream and putback is inserting it back in stream (if we do not know how to handle it). 对于read使用getputback来分析输入流: get从流中提取下一个字符,而putback将其插入流中(如果我们不知道如何处理它)。


Here it is a full solution ( try it ): 这是一个完整的解决方案尝试一下 ):

#include <iostream>
#include <cctype>

#define MAX_DIGITS 100

typedef int long_hex_t[MAX_DIGITS];

void add( long_hex_t c, long_hex_t a, long_hex_t b )
{
  int carry = 0;

  for ( int i = 0; i < MAX_DIGITS; ++i )
  {
    int t = a[i] + b[i] + carry;
    c[i] = t % 16;
    carry = t / 16;
  }
}

void print( long_hex_t h )
{
  //
  int i;

  // skip leading zeros
  for ( i = MAX_DIGITS - 1; i >= 0 && h[i] == 0; --i )
    ;

  // all zero
  if ( i < 0 )
  {
    std::cout << '0';
    return;
  }

  // print remaining digits
  for ( i; i >= 0; --i )
    std::cout << char( h[i] < 10 ? h[i] + '0' : h[i] - 10 + 'A' );
}

void read( long_hex_t h )
{
  // skip ws
  std::ws( std::cin );

  // skip zeros
  {
    char c;
    while ( std::cin.get( c ) && c == '0' )
      ;
    std::cin.putback( c );
  }

  //
  int count;
  {
    int i;
    for ( i = 0; i < MAX_DIGITS; ++i )
    {
      char c;
      if ( !std::cin.get( c ) )
        break;
      if ( !std::isxdigit( c ) )
      {
        std::cin.putback( c );
        break;
      }
      c = std::toupper( c );
      h[i] = c <= '9'
        ? ( c - '0' )
        : ( c - 'A' + 10 );
    }
    count = i;
  }

  // reverse
  for ( int i = 0, ri = count - 1; i < count / 2; ++i, --ri )
  {
    int t = h[i];
    h[i] = h[ri];
    h[ri] = t;
  }

  // fill the rest with zero
  for ( int i = count; i < MAX_DIGITS; ++i )
    h[i] = 0;
}

int main()
{
  long_hex_t a;
  read( a );

  long_hex_t b;
  read( b );

  long_hex_t c;
  add( c, a, b );

  print( c );

  return 0;
}

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

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