0

I am given two files one with the name of person and the location that they are from (Evan Lloyd|Brownsville) and one with the name and salary (Evan Lloyd|58697) (the line number that you find the employee on in the first file is not necessarily the line number that find the employee on in the second). The user inputs a location (whole or part). For example if they input "ville" or "Ville" it should include all of the employees in Brownsville, Clarksville, Greenville, etc. I am supposed to join the the name and salary and return them if they are in the city searched for i.e. "ville" or "Ville."

I have no errors or warnings when compiling, but I get a segmentation fault for all input.

#include <fstream>
#include <iostream>
//#include <vector>
#include <string>
#include <bits/stdc++.h>
using namespace std;

int main() {
    string str;
    cout << "Enter the location: ";
    cin >> str;
    ifstream addresses;
    addresses.open("personnel_addresses.txt");
    multimap<string, string> name_address;
    ifstream salaries;
    salaries.open("personnel_salaries.txt");
    multimap<string, string> name_salary;
    while(!addresses.eof() && !salaries.eof()) {
        string tmpstr;
        getline(addresses, tmpstr);
        int pos = tmpstr.find("|");
        string name2address = tmpstr.substr(0, pos - 1);
        string address = tmpstr.substr(pos + 1);
        name_address.insert({address, name2address});
        getline(salaries, tmpstr);
        pos = tmpstr.find("|");
        string name2employee = tmpstr.substr(0, pos - 1);
        string salary = tmpstr.substr(pos + 1);
        name_salary.insert({name2employee, salary});
    }
    // do{
    vector<string> employees;
    for(auto n = name_address.find(str); n != name_address.end(); n++) {
        employees.emplace_back(n->second);
    }
    for(int i = 0; i < sizeof(employees); i++) {
        string x = employees[i];
        //          if (name_salary.find(employees[i]))
        cout << employees[i] << ":" << name_salary.find(x)->second << "\n";
    }
    //}while(name_address.end());
    addresses.close();
    salaries.close();
    return 0;
}

Someone recommended that I alter the code by populating a set full of the cities in the while loop and iterating over the set immediately after declaring vectoremployees instead the code that directly below it by the following code

for(string const& search : cities)
{
if(find(search.begin(), search.end(), str) != std::string::npos)
{
string y = search;
employees.emplace_back(y);

, but there is something wrong with syntax where I am trying to iterate over the set.

EDIT: My problem was simple and was fixed with using .begin() and .end() to iterate over the multimap name_address and finding each name with .substr(). Also my while loop was incorrect. I should have read each file separate from each other. I did not use vectors in my solution.

while(getline(addresses, tmpstr1))
{
    int pos = tmpstr1.find("|");
    string name2address = tmpstr1.substr(0, pos);
    string address = tmpstr1.substr(pos+1);
    name_address.insert({address, name2address});
}   
while(getline(salaries, tmpstr2))
{
    int pos = tmpstr2.find("|");
    string name2employee = tmpstr2.substr(0, pos);
    string salary = tmpstr2.substr(pos+1);
    name_salary.insert({name2employee, salary});
}
  for(auto it = name_address.begin(); it != name_address.end(); ++it)
    {

        for(int i = 0; i < it->first.length(); ++i)
        {   
            string tmpstr3 = it->first.substr(0 + i, str.length());
            if(str == tmpstr3)
            {
               employees.insert(it->second);
               break;
            }
        }
    } 
JackLalane1
  • 177
  • 10
  • 3
    It helps if code is provided. – Tanveer Badar Jan 26 '20 at 20:34
  • 1
    Unrelated: [Don't `#include `](https://stackoverflow.com/Questions/31816095/Why-Should-I-Not-Include-Bits-Stdc-H.) – Ted Lyngmo Jan 26 '20 at 20:40
  • How do you properly format it? I was trying to paste the code, but it is all running together. – JackLalane1 Jan 26 '20 at 20:44
  • Copy the code from your IDE to the question. Select it and use the {} button to form a code block – drescherjm Jan 26 '20 at 20:48
  • I'd like to help, but firewalls are preventing me from following the code link. – Thomas Matthews Jan 26 '20 at 20:50
  • Should I attach the .txt files I am given as well? – JackLalane1 Jan 26 '20 at 21:00
  • Note: `while(!addresses.eof() && !salaries.eof())` will almost certainly cause problems. `eof()` will not be set when you've read the last line. It'll be set when you try to read passed the last line, so you will have failing `getline`s in that loop. – Ted Lyngmo Jan 26 '20 at 21:08
  • @TedLyngmo Oh, what should I use instead? – JackLalane1 Jan 26 '20 at 21:16
  • `std::string addr, sal; while(std::getline(addresses, addr) && std::getline(salaries, sal)) { ... }` would be a better option. – Ted Lyngmo Jan 26 '20 at 21:21
  • @TedLyngmo Would I have to declare string tmpstr (the entire line where the getline is stored) before the loop? – JackLalane1 Jan 26 '20 at 21:26
  • @JackLalane1 Yes, I replaced `tmpstr` with `addr` and `sal` above since you need to have both at the same time with this change. Like [this](https://godbolt.org/z/r3aGqz) – Ted Lyngmo Jan 26 '20 at 21:28
  • @TedLyngmo Okay, I changed that and it's not seg faulting now (I was using sizeof(vector) instead of vector.size()), but it is not outputing anything. I enter the input and it just goes back to the terminal. – JackLalane1 Jan 26 '20 at 21:50
  • @JackLalane1 Ok, good that it's not crashing. I guess you'll have to debug the code. Add printouts everywhere where the program has branches - or use a debugger to see where it goes wrong. – Ted Lyngmo Jan 26 '20 at 21:53
  • You may find [how to debug small programs](http://ericlippert.com/2014/03/05/how-to-debug-small-programs/) helpful. – JaMiT Jan 26 '20 at 22:31
  • Apparently the problem is in my first for loop. I have auto n = name_address.find(str); which apparently doesn't find substrings. For example, it returns partially correct if I enter "Louisville" instead of "Louis." – JackLalane1 Jan 26 '20 at 23:38

1 Answers1

1

A segmentation fault generally occurs when you are trying to access memory in some capacity, but have no permission to that location in memory. I notice that in one of your final for-loops, you say for(int i = 0; i < sizeof(employees); i++), but I believe that the function sizeof(object) reports the number of bytes in memory its parameter is consuming. It seems like that is not what you intended, and the number of bytes will most likely be much larger than the number of employees you are tracking. Thus, the body of your for-loop will try to access memory it is not allowed to and then cue a segmentation fault.

Another quick couple notes:

  1. Are you guaranteed that both of your input files will contain information about the same number of employees? If not, you will quit reading in from both files as soon as you made it to the end of one of them because of your looping condition.

  2. In most cases, I believe ifstream::eof() is pretty dangerous because it only indicates whether you have attempted to read past the end of a file. This usually means that you will perform more operations than you intended to. See here if you want more information from more knowledgeable people than I.

Shaavin
  • 125
  • 8