【问题标题】:2d array comparing with char与 char 比较的二维数组
【发布时间】:2022-01-19 06:27:49
【问题描述】:

我有一个从文件中读取数据的数组,数据是二进制数字,例如 010011001001 和许多其他数字,所以数据是我读入二维数组的字符串,但我坚持比较数组的每个值0. 任何帮助将不胜感激。

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main()
{
    string myArr[5000][12];
    int i = 0, zeroCount = 0, oneCount = 0;
    
    ifstream inFile;
    inFile.open("Day3.txt");
    
    while(!inFile.eof())
    {
        for(int i = 0; i < 5000; i++)
        {
            for(int j = 0; j < 12; j++)
            {
                inFile >> myArr[i][j];
                j++;
            }
            i++;
        }   
    }
    
    for(int j = 0; j < 12; j++)
    {
        for(int i = 0; i < 5000; i++)
        {
            if(myArr[i][j].compare("0") == 0)
            {
                zeroCount++;
            }
            else
            {
                oneCount++;
            }
            i++;
        }
        
        if(zeroCount > oneCount)
        {
            cout << "Gamma is zero for column " << i << endl;
        }
        else
        {
            cout << "Gamma is One for column " << i << endl;
        }       
        j++;
    }
}

来自文本文件的一些输入: 010110011101 101100111000 100100000011 111000010001 001100010011 010000111100

【问题讨论】:

  • 打开您的调试器并检查 myArr 的实际内容,如果您将文件作为二进制文件打开,那么我希望值 0 应该是 0 而不是 '0'(除非文件被写为文本文件然后它是'0')。
  • 包含所有二进制数字的文件保存为 .txt 文件,这会影响二进制数字的存储方式吗?还是我应该看看我的调试器?
  • 学习如何使用调试器无论如何都是一项很好的学习技能:) 一步一步地验证你的假设总是有帮助的。文件的内容取决于它的编写方式。并且解释可能取决于您打开文件的方式,文本可以有额外的解释(例如 UTF-8 编码)
  • 您显示的代码 sn-p 完全可以。错误在其他地方。您需要显示更多代码并且需要显示输入。然后我们可以给你一个更有帮助的答案。
  • @ArminMontigny 在像你这样的适当评论中,我建议使用方便的快捷方式minimal reproducible example[mre])。

标签: c++ arrays multidimensional-array


【解决方案1】:

感谢您编辑问题并提供更多信息。现在,我们可以帮助您。你有两个主要的误解。

  1. for 循环如何工作?
  2. 什么是 C++ 中的 std::string

让我们从 for 循环开始。您可以在 CPP 参考文献here 中找到解释。或者,您也可以查看here 显示的教程。

for 循环基本上有 3 个部分:for (part1; part2; part3)。都是可选的,可以用,但没必要用。

  • part1 是初始化语句。在这里您可以声明/定义/初始化一个变量。在您的情况下,它是int i = 0。您定义一个数据类型为 int 的变量并将其初始化为 0
  • part2 是条件。循环将运行,直到条件变为假。条件将在循环开始时检查。
  • part3 是所谓的迭代表达式。这个词有点误导。它基本上是在循环结束时执行的语句,在执行下一个循环运行之前以及再次检查条件之前。

在伪代码中是这样的:

{

    init-statement
    while ( condition ) {

        statement
        iteration-expression ;

    } 
} 

这意味着您的部分代码for(int j = 0; j &lt; 12; j++)

{

    int j = 0;                 // init-statement
    while ( j < 12 ) {         // while ( condition ) {

       inFile >> myArr[i][j];  // Your loop statements
       j++;                    // Your loop statements  PROBLEM

       j++;                    // iteration-expression from the for loop
    } 
} 

现在您看到了问题所在。不幸的是,您将“j”增加了两次。你不需要这样做。 for 循环的最后部分 3 已经为您完成了这项工作。

所以请删除重复的增量语句。


接下来,std::string

字符串,顾名思义,是一串字符,或者在编程语言的上下文中,是一个字符数组。

在 C 中,我们实际上写的是 char[42] = "abc";。所以使用真正的字符数组。问题始终是这样一个字符串的固定长度。这里以 42 为例。在这样的数组中,您只能存储 41 个字符。如果字符串更长,则无法正常工作。

C++ 的发明者解决了这个问题。他们创建了一个动态字符数组,一个可以根据需要增长的数组。他们称这件事为std::string。它没有预定义的长度。它会根据需要增长。

因此,写string myArr[5000][12]; 表明你没有完全理解这个概念。您不需要[12],因为string 已经可以容纳12 个字符。所以,你可以删除它。他们的角色将隐含地在那里。如果您编写 inFile &gt;&gt; myString,那么提取器运算符 &gt;&gt; 将从流中读取字符直到下一个空格,然后将其存储在您的 myString 变量中,无论字符串有多长。

请阅读this tutorial 了解字符串。

这是 C 样式字符串的一大优势。

那么您的代码可能如下所示:

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main()
{
    string myArr[5000];
    int zeroCount = 0, oneCount = 0;

    ifstream inFile;
    inFile.open("Day3.txt");

    while (!inFile.eof())
    {
        for (int i = 0; i < 5000; i++)
        {
            inFile >> myArr[i];
        }
    }

    for (int i = 0; i < 5000; i++)
    {
        zeroCount = 0; oneCount = 0;
        for (int j = 0; j < 12; j++) 
        {

            if (myArr[i][j]== '0')
            {
                zeroCount++;
            }
            else
            {
                oneCount++;
            }
        }

        if (zeroCount > oneCount)
        {
            cout << "Gamma is zero for column " << i << endl;
        }
        else
        {
            cout << "Gamma is One for column " << i << endl;
        }
    }
}

但还有更多。您对字符串数组使用幻数 5000。你这样做是因为你认为 5000 总是足够大以容纳所有字符串。但是,如果不是呢?如果您的源文件中有超过 5000 个字符串,那么您的代码将会崩溃。

与字符数组的字符串问题类似,我们也有一个用于 C++ 中任何类型数据的数组,它可以根据需要动态增长。它被称为std::vector,你可以阅读它here。教程可以在here找到。

这样您就可以完全摆脱任何 C 样式数组。但是请继续深入学习C++语言,你会越来越了解的。

您的代码中存在更微妙的问题,例如while(!inFile.eof()),但这应该稍后解决。

希望能帮到你

【讨论】:

  • 非常感谢您对我的代码中的问题的详细解释,我当然从中学到了很多东西。感谢您的帮助!
猜你喜欢
  • 2013-05-19
  • 2015-02-10
  • 1970-01-01
  • 1970-01-01
  • 2012-04-13
  • 1970-01-01
  • 2017-10-22
相关资源
最近更新 更多