【问题标题】:How do I clear the values in a string during each loop iteration?如何在每次循环迭代期间清除字符串中的值?
【发布时间】:2021-03-05 00:43:57
【问题描述】:

我想将不同的 b 值附加到我的原始数字,但在循环的一次迭代后(每次 cout 之后)将原始 num 值和 decVal 值刷新回空字符串和 0。我会怎么做那?例如,我没有返回 001 = 1, 011 = 3,而是得到 001 = 1, 001011 = 4。

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

void main()
{
    int n, decVal;
    int i = 7;
    string num, b, originalnum; 
    cin >> n;
    for (x = 0; x < n; ++i)
    {
        cin >> num;
        cin.get(b);
        cin.ignore();
        originalnum += b;
        decVal += atoi(&b) * pow(2, i);
        i -= 1;
        cout << "The decimal equivalent of " << originalnum << " = " << decVal << endl;
    }
}

【问题讨论】:

  • 声明要在循环内部而不是循环之前重置的字符串变量。 c++ 中的一个关键概念是将变量的范围限制在所需的最小范围内。
  • 有一个clear function 但@drescherjm 的建议更简洁。
  • 这段代码无法编译。您在一些地方缺少分号,atoi(&amp;b) 中的类型不匹配。
  • 除非您在独立环境中编程(没有任何操作系统的好处),在符合标准的实现中,main 的允许声明为int main (void)int main (int argc, char *argv[])(您将看到用等效的char **argv 编写)。见:What should main() return in C and C++?
  • 不要使用pow(2, i)。请改用1 &lt;&lt; i

标签: c++


【解决方案1】:

如果我理解您的要求,您希望能够重复输入位数并输出包含位表示和十进制值的字符串。您希望在 decVal 的不同迭代之间重置所有变量。为了实现这一点,除了修复一些错误,您只需将当前正在执行的操作包装在另一个循环中,这样对于外部循环的每次迭代,您都可以处理所有您喜欢的位,并得出最终的 @987654326 @ 输出。

在查看解决方案之前,正如上面评论中提到的,void main() 仅适用于独立环境(例如,没有操作系统,如微控制器等)。否则, main 的允许声明为 int main (void)int main (int argc, char *argv[])(您将看到用等效的 char **argv 编写)。见What should main() return in C and C++?

在方便的同时,您还需要阅读 Why is “using namespace std;” considered bad practice? 并了解 '\n'std::endl 之间的区别,请继续查看 C++: “std::endl” vs “\n”

您必须始终对每个输入做的一件事是通过在尝试输入之后和在使用输入填充的变量之前检查流状态来验证它是否成功。如果发生匹配失败,failbit 将被设置,并且您必须在尝试下一次输入之前清除错误位。您可以以任何您喜欢的方式处理错误,从结束程序,或通过清除错误位并删除导致.ignore() 问题的字符(两者的示例如下所示)。本质上,您至少需要以下内容:

        if (!(std::cin >> n)) {             /* validate EVERY user input */
            std::cerr << "invalid unsigned input -- exiting.\n";
            return 1;
        }

(注意:而不是仅仅调用.ignore(),你应该使用它的完整和正确的调用来删除任何特定情况下的最大数量的值。从文件流中读取时,即:std::cin.ignore (std::numeric_limits&lt;std::streamsize&gt;::max(), '\n');)

现在,对于您的程序设置,您基本上可以只使用与您所拥有的代码类似的连续循环,并提供一种机制以在用户完成输入值时退出外部循环。例如,使用简单的while(1) 循环并让用户输入除n 的有效数字以外的任何内容,您可以这样做:

    while (1) {                             /* outer loop - loop continually */
        size_t n;                           /* declare variables within loop */
        uint32_t decVal = 0;
        std::string originalnum {}; 
        
        std::cout << "\nenter no. of bits ('q' to quit): ";
        if (!(std::cin >> n)) {             /* validate EVERY user input */
            std::cerr << "invalid unsigned input -- exiting.\n";
            return 1;
        }

注意:所有变量都在循环内声明,因此对于每次迭代,每次都声明和初始化变量。上面告诉用户按'q' 退出——但可以输入任何不是有效数字的内容退出。这将简单地退出程序,将控制权返回给调用进程。

看看你的代码,pow() 函数确实不需要从用户输入的01 计算decVal。相反,您可以简单地将decVal 声明为unsigned 值(下面使用uint32_t 的精确值)并简单地使用Left-Shift 将每个输入移动当前循环计数器数位。

使用上面描述的左移来计算decVal(确保decVal在声明时初始化为零),并将用户输入添加到字符串的前面以保留LSB第一顺序,您可以这样做:

#include <iostream>
#include <iomanip>
#include <string>
#include <limits>
#include <climits>

int main (void)
{
    while (1) {                             /* outer loop - loop continually */
        size_t n;                           /* declare variables within loop */
        uint32_t decVal = 0;
        std::string originalnum {}; 
        
        std::cout << "\nenter no. of bits ('q' to quit): ";
        if (!(std::cin >> n)) {             /* validate EVERY user input */
            std::cerr << "invalid unsigned input -- exiting.\n";
            return 1;
        }
        if (n > sizeof (uint32_t) * CHAR_BIT) { /* validate EVERY value in range */
            std::cerr << "  error: n exceeds no. of bits avaialble.\n";
            return 1;
        }
        
        for (size_t i = 0; i < n;) {        /* inner loop, process bits */
            uint32_t bit;
            std::cout << " bit" << std::setw(2) << i << ": ";
            if (!(std::cin >> bit) || bit > 1) {
                std::cerr << "  error: invalid bit input.\n";
                std::cin.clear();
                std::cin.ignore (std::numeric_limits<std::streamsize>::max(), '\n');
                continue;
            }
            decVal += bit << i;                     /* no need for pow(), left-shift */
            originalnum.insert(0, 1, bit + '0');    /* build originalnum each iteration */
            i++;                                    /* increemnt on good input */
        }
        /* result */
        std:: cout << "The decimal equivalent of " << originalnum << 
                        " = " << decVal << '\n';
    }
}

注意:Numeric limits -- cppreference.com 显示每个使用的限制所需的头文件)

使用/输出示例

以下是与您显示的内容类似的输入和输出,但添加了提示以指导用户,并实施了错误处理以确保仅将有效的 01 作为输入:

$ ./bin/decval

enter no. of bits ('q' to quit): 3
 bit 0: 1
 bit 1: 1
 bit 2: 0
The decimal equivalent of 011 = 3

enter no. of bits ('q' to quit): 3
 bit 0: 1
 bit 1: 0
 bit 2: 0
The decimal equivalent of 001 = 1

enter no. of bits ('q' to quit): 3
 bit 0: 1
 bit 1: 0
 bit 2: pickles
  error: invalid bit input.
 bit 2: 1
The decimal equivalent of 101 = 5

enter no. of bits ('q' to quit): q
invalid unsigned input -- exiting.

如果您还有其他问题或我误解了您的意图,请查看并告诉我。

【讨论】:

    【解决方案2】:

    只清除后面的字符串

    cout << ... << endl;
    

    试试这个

    #include <iostream>
    #include <iomanip>
    #include <string>
    using namespace std;
    
    void main()
    {
        int n, decVal;
        int i = 7;
        string num, b, originalnum; 
        cin >> n;
        for (x = 0; x < n; ++i)
        {
            cin >> num;
            cin.get(b);
            cin.ignore();
            originalnum += b
            decVal += atoi(&b) * pow(2, i);
            i -= 1
            cout << "The decimal equivalent of " << originalnum << " = " << decVal << endl;
            originalnum = "";
            n = 0;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2015-04-09
      • 1970-01-01
      • 2016-07-29
      • 1970-01-01
      • 1970-01-01
      • 2014-10-31
      • 1970-01-01
      • 2023-03-29
      • 2012-09-10
      相关资源
      最近更新 更多