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

时间:2017-11-08 05:47:04

标签: c++

编写一个C ++程序,添加两个长度小于100位的十六进制数字。使用数组将十六进制数字存储为字符数组。解决方案是直接以十六进制格式添加相应的数字。如果当前数字的总和超过16,从右到左,在左边的数字上加一个。当两个数字有不同的数字时,你应该能够处理这个情况。

获取输入的正确方法是存储为字符数组。您可以先存储在字符串中并转换为字符数组,也可以使用cin.getline(), getc()cin.get()等方法读取字符。

我不知道我的程序有什么问题,而且我不知道如何使用函数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;
    }
   }
}

3 个答案:

答案 0 :(得分:2)

让我们看看cin.getline做了什么:

  

从流中提取字符直到行尾。建成后   并检查哨兵对象,从* this和中提取字符   将它们存储在第一个元素的数组的连续位置   s指出,直到发生以下任何一种情况(在   订单显示):

     
      
  • 文件结束条件发生在输入序列中(在这种情况下执行setstate(eofbit))
  •   
  • 下一个可用字符c是分隔符,由Traits :: eq(c,delim)确定。提取分隔符(与basic_istream :: get()不同)并计入gcount(),但不存储。
  •   
  • 已提取count-1个字符(在这种情况下执行setstate(failbit))。
  •   
     

如果函数不提取任何字符(例如,如果count <1),则setstate(failbit)   被执行。在任何情况下,如果count> 0,则它存储空字符   CharT()进入数组的下一个连续位置并进行更新   gcount的()。

结果就是在所有情况下,s现在指向一个以空字符结尾的字符串,最多为count-1个字符。

在您的使用中,您最多可以使用99位数,并且可以使用strlen来计算确切数量。 eof不是字符,也不是char的成员函数。

然后,您可以反转输入,然后进行过度重复的转换。

然而,使用函数要简单得多,无论是你自己写的还是标准提供的函数。

// 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();
}

答案 1 :(得分:1)

这是一个很长的答案。因为你的代码中有很多错误。你使用getline是好的。但是你正在调用像e.eof()这样的eof(),这是错误的。如果你看过你的编译错误,你会发现它抱怨在变量e上调用eof(),因为它是非类型的。简单的含义它不是某个类的对象。您不能将点运算符.放在这样的基本类型上。我想你想要做的是,当你到达行尾时终止循环。这样index1和index2就可以得到字符串输入的长度。如果我是你,我会使用C ++内置strlen()函数。首先,您应该使用C ++类string来处理字符串。字符串也有一个空终止字符&#39; \ 0&#39;在他们的最后。如果你不了解它,我建议你花些时间阅读字符串。

其次,您的代码中存在许多错误和错误。你反转字符串的方式是不正确的。问问自己,位置上的数组ab的内容是什么,其索引的索引高于字符串的长度?您应该使用reverse()来反转字符串和数组。

添加循环时也有错误。请注意,对于具有相应小数值10,11的十六进制值,您要更改数组值ABCD等等, 12,13等。但是你应该改变角色的价值&#39; 0&#39; - &#39; 9&#39;也。因为当数组保持&#39; 0&#39;它不是整数0.但是ASCII是&#39; 0&#39;它的整数值为48.而字符&#39; 1&#39;整数值为49,依此类推。您还希望将此值替换为相应的整数值。当您还将结果值存储在c中时,您只处理那些大于9的值并用相应的字符替换它们。您还应该用相应的ASCII字符替换整数0 - 9。也不要忘记在结果的末尾添加一个空终止字符。

此外,当p大于15时,您只是更改了随身携带,但您也应相应更改p

我相信你可以以更优雅的方式反转结果数组c。仅在完全执行计算时进行反转。您可以为此简单地致电reverse()

我相信你可以多思考一下,并以正确的方式编写代码。我有一些建议,不要使用变量名,如a,b,c,o。尝试用他们真正做的事来命名变量。此外,您可以通过算法中的一个简单更改来改进算法并缩短代码和头痛。首先找到a的长度,然后找到b的长度。如果长度不相等,找出长度较短的长度。然后在它前面添加0以使两个长度相等。现在,您可以从后面开始,然后执行添加。此外,您应该使用内置方法,例如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;

}

答案 2 :(得分:1)

关于问题的文字“如果当前数字的总和超过16”,则向左边的数字添加1; 它应该是15,而不是16。

关于您的代码:我没有耐心阅读您的所有代码,但是:

  • 我注意到一个长if/else。使用switch(但您不需要)。
  • 要查明某个字符是否为十六进制数,请使用isxdigit#include <cctype>)。
  • 用户可能输入大写和小写字符:使用toupper / tolower将它们转换为相同的大小写。
  • 要将十六进制数字转换为整数:
    • 如果数字在'0'和'9'之间,则简单地减去'0'。这是因为'0','1'的代码是0x30,0x31 ......(谷歌ASCII码)。
    • 如果数字位于“A”和“F”之间,则减去“A”并添加10。

解决问题

  • “长度不足100位”这是关于如何存储数据的明确指示:一个简单的100长数组,没有std::string,没有{{1 }}:

    std::vector

    换句话说,您的号码最多为100位数。

    决定如何存储号码:最低有效数字的第一个还是最后一个?我会选择存储最不重要的第一个。 123存储为{3,2,1,0,... 0}

  • 使用函数简化代码。您需要三个功能:#define MAX_DIGITS 100 typedef int long_hex_t[MAX_DIGITS]; readprint

    add
  • 最简单的写作函数是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; } ,然后是addprint

  • read使用readget分析输入流:putback从流中提取下一个字符,get将其插入流中(如果我们不知道如何处理它)。


这是完整解决方案try it):

putback