1

I'm writing a program that allows a user to type in a file name of a person database to be read; the program then creates a linked list of state objects and a linked list of person objects within each state link to organize the information from the file.

I know the linked list part works because I was able to directly code in the file name and print out the list of states and the list of people in each state; however, when I try to allow the user to type in the file name as a command, I'm getting a Bus error. When I run the code in gdb, all it tells me is:

Program received signal SIGBUS, Bus error.
0x280df0bd in std::operator>><char, std::char_traits<char> > ()
   from /usr/lib/libstdc++.so.5

I don't even get a line number to go off of! Any help would be super appreciated. Here's the command and read portions of my code:

List<State*>* read(char* filename) {
    string fname, lname, birthday, state;
    int ssn;
    List<State*>* state_list = new List<State*>();

    ifstream file(filename);
    if (file.fail()) {
        cerr << "Error reading file.\n";
        exit(1);
    }

    while (!file.eof()) {
        file >> birthday >> ssn >> fname >> lname >> state;
        Link<State*>* searchres = searchList(state, state_list);
        Person* p = new Person(fname, lname, ssn, birthday, state);
        if (searchres == NULL) // create new state
        {
            State* addedstate = state_list->addLink(new State(state))->data;
            addedstate->res_list.addLink(p);
        }

        else // add to pre-existing state
        {
            searchres->data->res_list.addLink(p);
        }
    }
    return state_list;
}

void main() {
    string cmd;
    cout << "Type your command in all lowercase letters.\n";
    cin >> cmd;
    if (cmd == "read") {
        char* filnm;
        cin >> filnm;
        List<State*>* state_ls = read(filnm);
        Link<Person*>* counter = state_ls->first->data->res_list.first;
        while (counter != NULL) {
            cout << counter->data->ssn << "\n";
            counter = counter->next;
        }
    }
}
NetVipeC
  • 4,284
  • 1
  • 14
  • 19
jiccan
  • 89
  • 9
  • dont use `file.eof()`. It may even be your problem here. – dwcanillas Apr 16 '15 at 20:26
  • see http://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong – dwcanillas Apr 16 '15 at 20:26
  • Might file.fail() be a better condition? Or something else entirely? – jiccan Apr 16 '15 at 20:27
  • fail might be better, I'm not sure what the best thing to do is while you are reading multiple variables at once. You may be able to put the whole line where you read into the while condition. – dwcanillas Apr 16 '15 at 20:29
  • @sar - It's `int main()`, not `void main()`. – PaulMcKenzie Apr 16 '15 at 20:36
  • I know that's technically the more appropriate return type (I'm very clearly a novice programmer who was taught to use void). But in this case, does int vs. void make a difference with regard to the error I'm getting? Just out of curiosity! – jiccan Apr 16 '15 at 20:39
  • @sar - `I'm very clearly a novice programmer who was taught to use void` If you paid money for that course, demand a refund. – PaulMcKenzie Apr 16 '15 at 20:41
  • @PaulMcKenzie -- it was a multi-thousand-dollar college course lol. Nobody seems to be able to answer my questions, either! I've been nagging people for days and I've been getting really vague answers. Most of my errors were solved using stackoverflow answers. – jiccan Apr 16 '15 at 20:47
  • @sar Strictly speaking, declaring `main` wrong is an instance of undefined behaviour (anything can happen as far as the standard is concerned). In practice, this particular mistake won't have any more repercussions than a garbage return value. However, it's unwise to start nitpicking the standard with "oh well it may just work". Until you're piecing together register values by hand, apply the standard and crank up the compiler warnings, everyone will be better off. – Quentin Apr 16 '15 at 20:50
  • Unfortunately, C is one of those languages that allow a lot of "not proper" things, and thus bad teachers teach things that aren't right - do complain to the organiser of the course, as it's not just bad for you, but also to the course organiser... – Mats Petersson Apr 16 '15 at 20:51
  • @sar Unfortunately it seems that it is very difficult to find good C++ courses or teachers. You have to get books written by the known "pros" in the business, and/or come to sites like SO where you get real-world answers. – PaulMcKenzie Apr 16 '15 at 20:51
  • In fact, there are so many things wrong in this code snippet. Indentation. Naked pointers. Bogus `while(!eof)`. Needless dynamic allocation, and assorted memory leaks. Brutal exit from inside a function. Badly scoped variables. Const correctness. Please don't take this personally, @sar, as you can't know better, but if that's what is taught to you it's wasting quite a bit of your time and money. And I am really sorry for you :( – Quentin Apr 16 '15 at 20:59
  • @Quentin -- Very good point. I really ought to start aligning my codes to the accepted standards when it comes to things like that. Thank you! – jiccan Apr 16 '15 at 21:00
  • @Quentin, are you serious? Oh my god no one ever says anything to suggest there's anything wrong! Well, this is embarrassing. – jiccan Apr 16 '15 at 21:02
  • @sar - Learn `std::list` by replacing your `List` class with `std::list`. At lease half the code you have now would go away, and would be closer to having no issues whatsoever. – PaulMcKenzie Apr 16 '15 at 21:11
  • @sar Well, I admit to have searched a bit hard for problems, and they're not all critical, but they are there. Well... I don't know what to say. It may be awkward to approach your teacher(s) with a defects dump from some guy on the internet. In any case, I recommend [codereview.se] when you have a self-contained, working program and want knowledgeable people to check it for such problems. Feel free to come back here and ask questions about precise problems (caution not to repost !). – Quentin Apr 16 '15 at 21:20
  • @sar Last thing : in the (probable) case that you seek more C++ learning material on internet, do triple-check everything you find. You wouldn't believe how much of that material is vague or plain wrong. SO is generally well-furnished in good advice though, and even if it's not structured as a learning resouce it did help me a lot. Best of luck ! – Quentin Apr 16 '15 at 21:23
  • Thank you all so very much. This is only my second semester in coding so I think my professors are trying to teach us the logic and then, as we get exposed to more real-word coding, they'll be more strict about stylization and formatting. This was definitely an eye-opener though. And thank you for reformatting my code! Now I have at least a little bit more of an idea where I'm going wrong. Again, much appreciation for everyone who taught me a thing or two with this one. :) – jiccan Apr 16 '15 at 22:14

1 Answers1

7

Right away, you have a problem:

char* filnm;
cin >> filnm;

The pointer is uninitialized, yet you read in information using that pointer.

Either use std::string, or a char array that is appropriately sized.

To use a std::string in the open of the file:

std::string filnm;
cin >> filnm;
read(filnm.c_str());

Your read function should also change the parameter to const char* instead of char *. You are not changing the contents of the character array being passed, so it should be const.

Edit: You actually do not need to use c_str(), as the std::string has a constructor that takes a const char*. Still, change the parameter to const char *filename in the read() function.

PaulMcKenzie
  • 31,493
  • 4
  • 19
  • 38
  • I tried using string, but for some reason opening the file only works if the filename variable is a char*. Should I be able to write ifstream file(filename) if filename is a string instead of a char*? – jiccan Apr 16 '15 at 20:35
  • No it does not *work* using just `char*` like that. The pointer is uninitialized, thus the behavior is *undefined*. Undefined means anything can happen. See my edit. – PaulMcKenzie Apr 16 '15 at 20:37
  • Wonderful! I got it, finally, setting the size of the char array. If you don't mind my asking, how exactly could you use string? I'd like -- if possible -- to get around the need to set the size of the char array myself, because who knows how long the filename might be. I've already included string in my header (along with cstring and cctype, just in case). – jiccan Apr 16 '15 at 20:45
  • Either use `getline(cin, filnm)` or `cin >> filnm` as my edit shows. Use the former if you expect to get file names with spaces in them (so the `getline` may be the better option). – PaulMcKenzie Apr 16 '15 at 20:49
  • THANK YOU SO SO MUCH! I have learned more in the past 15 minutes than I have in the past three days of working on this code. Wholly appreciated. – jiccan Apr 16 '15 at 20:58
  • @sar Don't forget to accept one of the answers (not much competition here I'm afraid) ;) – Quentin Apr 16 '15 at 21:27