为什么编码挑战的解决方案看起来比我的复杂得多,而我的却更简单?

Why does the solution to a coding challenge seem so much more complex than mine, while mine is simpler?

我正在学习 C++ 课程,每个部分都有一个挑战。对于最近的挑战,我们要从一个文本文件中取出三种不同类型的数据,在一行中有三种数据类型,每种数据类型由一个制表符分隔(您将看到只有两个制表符)。

1\tBox of 64 Pixels\t64 RGB pixels in a decorative box
2\tSense of Humor\tEspecially dry. Imported from England.
3\tBeauty\tInner beauty. No cosmetic surgery required!
4\tBar Code\tUnused. In original packaging.

第一种是SKU号,第二种是品名,第三种是描述。您必须将所有这些信息放在一个结构中。

我的解决方案:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>

using namespace std;

struct CI
{
  int sku = 0;
  string name = "";
  string desc = "";
};

const int MAXSTRING = 1024;

int main()
{
  const char *itemsPath = "items.txt";

  FILE *items = fopen(itemsPath, "r");

  CI changed1;
  CI changed2;
  CI changed3;
  CI changed4;
  vector<CI> changed = {changed1, changed2, changed3, changed4};

  vector<string> lines = vector<string>();

  char buffer[MAXSTRING];

  int tab = 0;
  int counter = 0;

  while (fgets(buffer, MAXSTRING, items))
  {
    lines.push_back(buffer);
  }

  for (string &s : lines)
  {
    for (char &c : s)
    {
      if (c == '\t')
      {
        tab++;
        continue;
      }

      if (tab == 0)
      {
        changed[counter].sku = c - '0';
      }
      else if (tab == 1)
      {
        changed[counter].name += c;
      }
      else if (tab == 2)
      {
        changed[counter].desc += c;
      }
    }
    tab = 0;
    counter++;

    if (counter == 4)
    {
      break;
    }
  }

  for (int i = 0; i < 4; i++)
  {
    cout << "sku: " << changed[i].sku << ", name: " << changed[i].name << ", desc: " << changed[i].desc;
  }

  fclose(items);

  return 0;
}

实际解决方案:

// 08_solution.cpp by Bill Weinman <http://bw.org/>
// updated 2002-07-23
#include <cstdio>
#include <cerrno>
#include <cstdlib>
#include <cstring>

constexpr size_t maxstring = 1024; // size of line buffer
constexpr size_t name_size = 32;   // size of name string
constexpr size_t desc_size = 128;  // size of description string
constexpr const char *filename = "/Users/billw/Desktop/ExerciseFiles/Chap08/items.txt";
constexpr size_t max_split = 15;
constexpr char tab_char = '\t';

struct Item
{
  int sku;              // stock keeping unit
  char name[name_size]; // item name
  char desc[desc_size]; // item description
};

// str_seps(s) -- returns an array where each element
// represents the position of a separator in the string
// first element is a count
size_t *str_seps(const char *s, size_t len)
{
  static size_t indicies[max_split + 1];
  size_t &count = indicies[0];
  if (len < 3)
    return indicies;
  for (size_t &z : indicies)
    z = 0; // zero out the array

  for (size_t i = 0; i < len; ++i)
  {
    if (s[i] == tab_char)
    {
      ++count;
      indicies[count] = i;
      if (count >= max_split)
        break;
    }
  }
  return indicies;
}

int main()
{
  char buf[maxstring]; // buffer for reading lines in file

  // open the file
  FILE *fr = fopen(filename, "r");
  if (!fr)
  {
    const char *errstr = strerror(errno);
    printf("cannot open file (%d): %s\n", errno, errstr);
    return 1;
  }

  // read loop
  while (fgets(buf, maxstring, fr))
  {
    size_t len = strnlen(buf, maxstring);
    if (len <= 5)
      continue;

    // trim the newline from the end of the string
    if (buf[len - 1] == '\n')
    {
      buf[len - 1] = 0;
      --len;
    }

    size_t *split3 = str_seps(buf, len);
    if (split3[0] < 2)
      break;
    buf[split3[1]] = buf[split3[2]] = 0; // change separators to terminators

    Item current_item;
    current_item.sku = atoi(buf);
    strncpy(current_item.name, buf + split3[1] + 1, name_size - 1);
    strncpy(current_item.desc, buf + split3[2] + 1, desc_size - 1);
    printf("sku: %d, name: %s, desc: %s\n", current_item.sku, current_item.name, current_item.desc);
  }
  return 0;
}

已编辑:具体来说,我的代码是否不安全,是否检查文件是否已打开:

  if (!fr)
  {
    const char *errstr = strerror(errno);
    printf("cannot open file (%d): %s\n", errno, errstr);
    return 1;
  }

需要。

关于为什么它看起来很奇怪的一个提示是在一开始:

// updated 2002-07-23
#include <cstdio>
#include <cerrno>
#include <cstdlib>
#include <cstring>

所以 20 年前的代码,只使用 C 库,可能不是很棒的 C++。

另一方面,代码如下:

  CI changed1;
  CI changed2;
  CI changed3;
  CI changed4;
  vector<CI> changed = {changed1, changed2, changed3, changed4};

也可能只对编写它的人显而易见。 :-)

猜想vector<CI> changed(4);的意思一样,不过想了想