1

I am new to Protocol Buffers and inexperienced with C++, I am trying to complete the tutorial at https://developers.google.com/protocol-buffers/docs/cpptutorial

I've created the proto file mentioned in the tutorial and gotten addressbook.pb.h and addressbook.pb.cc from this proto. I am trying to follow the segment "Writing A Message", so I copied and pasted the following code from the tutorial. I immediately run into an issue in the main function, which I'll explain below:

#include <iostream>
#include <fstream>
#include <string>
#include "addressbook.pb.h"
using namespace std;

// This function fills in a Person message based on user input.
void PromptForAddress(tutorial::Person* person) {
  cout << "Enter person ID number: ";
  int id;
  cin >> id;
  person->set_id(id);
  cin.ignore(256, '\n');

  cout << "Enter name: ";
  getline(cin, *person->mutable_name());

  cout << "Enter email address (blank for none): ";
  string email;
  getline(cin, email);
  if (!email.empty()) {
    person->set_email(email);
  }

  while (true) {
    cout << "Enter a phone number (or leave blank to finish): ";
    string number;
    getline(cin, number);
    if (number.empty()) {
      break;
    }

    tutorial::Person::PhoneNumber* phone_number = person->add_phone();
    phone_number->set_number(number);

    cout << "Is this a mobile, home, or work phone? ";
    string type;
    getline(cin, type);
    if (type == "mobile") {
      phone_number->set_type(tutorial::Person::MOBILE);
    } else if (type == "home") {
      phone_number->set_type(tutorial::Person::HOME);
    } else if (type == "work") {
      phone_number->set_type(tutorial::Person::WORK);
    } else {
      cout << "Unknown phone type.  Using default." << endl;
    }
  }
}

// Main function:  Reads the entire address book from a file,
//   adds one person based on user input, then writes it back out to the same
//   file.
int main(int argc, char* argv[]) {
  // Verify that the version of the library that we linked against is
  // compatible with the version of the headers we compiled against.
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  if (argc != 2) {
    cerr << "Usage:  " << argv[0] << " ADDRESS_BOOK_FILE" << endl;
    return -1;
  }

  tutorial::AddressBook address_book;

  {
    // Read the existing address book.
    fstream input(argv[1], ios::in | ios::binary);
    if (!input) {
      cout << argv[1] << ": File not found.  Creating a new file." << endl;
    } else if (!address_book.ParseFromIstream(&input)) {
      cerr << "Failed to parse address book." << endl;
      return -1;
    }
  }

  // Add an address.
  PromptForAddress(address_book.add_person());

  {
    // Write the new address book back to disk.
    fstream output(argv[1], ios::out | ios::trunc | ios::binary);
    if (!address_book.SerializeToOstream(&output)) {
      cerr << "Failed to write address book." << endl;
      return -1;
    }
  }

  // Optional:  Delete all global objects allocated by libprotobuf.
  google::protobuf::ShutdownProtobufLibrary();

  return 0;
}

In the main function the code exits without prompting for any inputs due to this portion:

  if (argc != 2) {
    cerr << "Usage:  " << argv[0] << " ADDRESS_BOOK_FILE" << endl;
    return -1;
  }

which appears as one of the first few lines in the function, before any inputs are requested. I read that argc will be the number of inputs. I'm confused because I copied and pasted exactly what the tutorial wrote, but it doesn't appear to be running correctly.

jalconvolvon
  • 158
  • 1
  • 10
  • What does *the code gets stuck* mean? Do you mean you get a compiler error? If so, what is the **exact** error message? If it's not a compiler error, what **specifically** is the problem? If you want help with your problem, you need to explain the problem clearly. – Ken White Jul 23 '15 at 17:54
  • The code exits without prompting for any inputs. When I add an input before "return -1" it pauses and the output reads "Useage: C:\Stuff\ProtoExample.exe ADDRESS_BOOK_FILE. I'll update the question with this information – jalconvolvon Jul 23 '15 at 18:00
  • If I comment out all of the "if (argc != 2)" lines, I receive the following error: Debug Assertion Failed! File: f:\dd\vctools\crt_bld\self_x86\crt\src\fopen.c Expression: (file != NULL) – jalconvolvon Jul 23 '15 at 18:12

1 Answers1

2

That code expects a file name to be passed on the command line, not read from stdin. You've not specified what platform you're on, but you'll do something like my_program.exe C:\some\file\somewhere on Windows or ./my_program /some/file/somewhere on Linux/Mac/Other Unix like OS. If you're running the program from your IDE's run/debug function then you'll need to configure it to pass the name of the file as a command line argument. How to do that will depend on what IDE you're using.

Miles Budnek
  • 28,216
  • 2
  • 35
  • 52
  • Thank you for pointing me in the right direction. How would I do this on Windows using Visual Studio 2010 from the debug function? I've created an empty document named myBook.txt, would I do something like myString="C:\something\myBook.txt" ? – jalconvolvon Jul 23 '15 at 18:31
  • 1
    For Visual Studio, right-click your solution and choose properties. Select Debugging under Configuration Properties and put `C:\path\to\your\file` in the Command Arguments box. You'll need to put the path in quotes if it contains any spaces. – Miles Budnek Jul 23 '15 at 18:34