How to remove a character

I have a program that gets a city name from a file, but there are some that have a underscore between there names, how do i remove them by using a function.

Example
From: New_York_City
To: New York City
Last edited on
There are many ways one could do this. The second solution doesn't use any functions, but it still does the job.

1
2
3
4
5
6
7
8
9
#include <iostream>
#include <string>

int main(void) {
	std::string str = "New_York_City";
	while(str.find('_') != std::string::npos)
		str.replace(str.find('_'), sizeof(' '), " ");
	std::cout << str << '\n';
}

** Correction made by andywestken.

1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
#include <string>

int main(void) {
	std::string str = "New_York_City";
	for(int i = 0; str[i] != '\0'; ++i) {
		if(str[i] == '_')
			str[i] = ' ';
	}
	std::cout << str << '\n';
}
Last edited on
how would you include that in this

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
#include <iostream>
#include <fstream>
#include <cmath>
#include <string>
using namespace std;

const int MAX_ARRAY = 1200;          // Max number of zip code entries
const int DELTA_ZIP = 48710;          // Base zip code for Delta College
const double DELTA_LAT = 43.55660;    // Delta College latitude
const double DELTA_LON = -83.99430;   // Delta College longitude (neg. for N. Hemi.

typedef char StateType[3];            // Data type for state char. strings (max 2 char)
typedef char CityType[31];            // Data type for city char. strings (max 30 char)

void getData(ifstream& inFile, int zip[], double lat[], double lon[],
             StateType state[], CityType city[], int& numVals);
int binarySearch(int array[], int numelems, int value);
double GreatCircleDist(double la1, double lo1, double la2, double lo2);
double Deg_Rad(double angle);
string strMonth[12]= {"January" , "February" , "March" , "April" , "May" , 
"June" , "July" , "August" , "September" , "October" , "November" ,
 "December" };
void DateCheck(int, int ,int);
void Remove(string);

int main()
{
    ifstream fileIn;    // Input file identifier               
    
    // Declare parallel arrays for zip code data
    int zip[MAX_ARRAY];           // Array for zip codes
    double latitude[MAX_ARRAY];   // Array for latitudes
    double longitude[MAX_ARRAY];  // Array for longitudes
    StateType state[MAX_ARRAY];   // Array for states
    CityType city[MAX_ARRAY];     // Array for cities

    double distance;              // Calculated distance from base zip to target
    int numElems;                 // Actual number of values in array 
                                  // (1 more than largest index)
    int index;                    // Search outcome
                                
                                
    int month, day, year, targetZip;
    cout << "Enter Shipping Date: mm/dd/yy "<< endl;
    cin >> month >> day >> year ;              // Zip code of desired community                    

    fileIn.open("zipMIcity.txt");   // Open file
    
    if (fileIn.fail() )         // Test for file existence
    {
      cout <<  "Problem opening file";
      exit(-1);
    }
    
    // Read file and count values in array
    getData(fileIn,zip,latitude,longitude,state,city,numElems);

    // Prompt user for source zip code:
    
    cout << "Enter your target zip code: "<< endl;
    cin  >> targetZip;
   
    // Search for index of desired zip code and Delta's
    // zip code
    index = binarySearch(zip, numElems, targetZip);
    
    if (index >= 0)
    {
        // Calculate great circle distance from Delta to target post
        // office using index found with search.  Convert geographical
        // coordinates from degrees to radians for use in formula
        distance = GreatCircleDist(DELTA_LAT,DELTA_LON,
                                   latitude[index],longitude[index]);                                                     
        // Write output
         
        cout << endl << endl;
        DateCheck(month, day, year);
        cout << "Distance from Delta College to" << endl;
        Remove(city[index]);
        cout << ", " << state[index];
        cout << " (Zip Code: " << targetZip  << ")" <<endl;
        cout << "is " << distance << " miles" << endl << endl;
    }
    else
        cout << endl << "Error: Zip code not found" << endl << endl;

    // Close file
    fileIn.close(); 
       
    
    system("pause");
    return 0;                
}

//***************************************************************
// This function reads 3 sets of integers from a file and stores
// the values in an array.  It returns the loaded arrays and the
// number of elements in the array
// File format:  zip_code  latitude  longitude
//***************************************************************
void getData(ifstream& inFile, int zip[], double lat[], double lon[],
             StateType state[], CityType city[], int& numVals)
{
    int i = 0;
    
    inFile >> zip[i] >> lat[i] >> lon[i] >> state[i] >> city[i];          
    while (!inFile.eof() && i < MAX_ARRAY)        
    {
       i++;        
       inFile >> zip[i] >> lat[i] >> lon[i] >> state[i] >> city[i];          
    }            
    numVals = i;
}

//***************************************************************
// The binarySearch function performs a binary search on an   
// integer array. array, which has a maximum of numelems      
// elements, is searched for the number stored in value. If the
// number is found, its array subscript is returned. Otherwise,
// -1 is returned indicating the value was not in the array.  
//***************************************************************
int binarySearch(int array[], int numelems, int value)
{
    int first = 0,                 // First array element
        last = numelems - 1,       // Last array element
        middle,                    // Mid point of search
        position = -1;             // Position of search value
    bool found = false;            // Flag

    while (!found && first <= last)
    {
        middle = (first + last) / 2;     // Calculate mid point
        if (array[middle] == value)      // If value is found at mid
        {
            found = true;
            position = middle;
        }
        else if (array[middle] > value)  // If value is in lower half
            last = middle - 1;
        else
            first = middle + 1;          // If value is in upper half
    }
    return position;
}

//***************************************************************
// This function receives two sets of geographical coordinates
// and returns the great circle distance betweent them.       
// Preconditions:                                             
//    Latitude/longitude values in radians                    
//    Value ranges:  -90.0 ² Latitudes ² 90.0                 
//             -180.0 ² Longitudes <= 180.0                   
// Postconditions:                                         
//    Coordinate parameters are unchanged                     
//    Return value (distance) in kilometers                   
//***************************************************************
double GreatCircleDist(double la1, double lo1, double la2, double lo2)
{
  const double RADIUS_EARTH = 3963.189; // in miles

  // Convert local variables to radians  
  la1 = Deg_Rad(la1);
  lo1 = Deg_Rad(lo1);
  la2 = Deg_Rad(la2);
  lo2 = Deg_Rad(lo2);
  return RADIUS_EARTH * acos( sin(la1) * sin(la2) 
                      + cos(la1) * cos(la2) * cos(lo2-lo1) );
}

//***************************************************************
// This function receives a value in degrees and returns the 
// equivalent angle in radians                               
//***************************************************************
double Deg_Rad(double angle)
{
   double const pi = 3.1415926;
   return angle * pi / 180.0;
}

void DateCheck(int month, int day, int year)
{
  if (month<0 && month>12)
  cout << "Error: Month is not between 1-12.";
  else if (day<0 && day>31)
  cout << "Error: Day is not between 1-31.";
  else if (year<2000 && year>2099)
  cout << "Error: Year is not between 2000-2099.";
  else 
  cout<< "To be shipped on: "<< strMonth[month-1] <<" "<< day << ", " << year<<endl;
}
void Remove(string city[index])
{
	string str = city[index];
	for(int i = 0; str[i] != '\0'; ++i) {
		if(str[i] == '_')
			str[i] = ' ';
	}
	cout << str << '\n';
}
Last edited on
@buddy208,

In about 3 steps.

#1 Rename the main func() in xhtmlx's example to, say,
int city_underscore(void)
As it stands, it is well written and doesn't need to be changed.

#2
You have the statement:
std::string str = "New_York_City";

so change it to get the cities from your cities array:
city[MAX_ARRAY]; in line 35 (above)


#3
Load the array
call the func()
run as normal

ps #4, refer to your original detailed design.


Last edited on
@xhtmlx

The first of your little program outputs

New ork ity

as you're using sizeof(" ") when I assume you meant to use sizeof(' ')

1
2
3
4
5
6
7
8
9
10
#include <iostream>
#include <string>

int main(void) {
	std::string str = "New_York_City";
	while(str.find('_') != std::string::npos)
		str.replace(str.find('_'), sizeof(' '), " ");
                // now sizeof(' ') not sizeof(" ")
	std::cout << str << '\n';
}


But as you're just replacing a single char, I don't see the point of using replace. operator[] is what's appropriate here.

I think the second program is the better one as it walks the string just the once, rather than re-searching the string twice to replace each _

Andy

PS If you are going for a "function based" solution, a better one might be

1
2
3
4
5
6
7
8
9
10
#include <iostream>
#include <string>

int main(void) {
	std::string str = "New_York_City";
	std::string::size_type pos = 0;
	while(std::string::npos != (pos = str.find('_', pos)))
		str[pos++] = ' ';
	std::cout << str << '\n';
}


but the best solution is the std::replace algorithm

1
2
3
4
5
6
7
8
9
#include <iostream>
#include <string>
#include <algorithm>

int main(void) {
	std::string str = "New_York_City";
	std::replace(str.begin(), str.end(), '_', ' ');
	std::cout << str << '\n';
}


Last edited on
as you're using sizeof(" ") when I assume you meant to use sizeof(' ')

Yes, sorry about that. I had it working and then changed it after I had realized another mistake made. I'll be sure to test my code next time I post something.
Last edited on
Topic archived. No new replies allowed.