String functions

Hi! I recently had to write a program in which a user would input a file name, and the program would spit out a version of the file name. Specifically, if the user enter something like "file.input", "file", "file.in" or "file.data", the program is supposed to print out "file.output". Here is what I have thus far:

#include<iostream>
#include<string>

using namespace std;

int main()
{
string s;
cout << "enter name: " << endl;
cin >> s;

for (int i = 0; i < s.length(); i++)
{
if (s.substr(i, 3) == ".in")
{
s.replace(i, 3, ".output");
}

if (s.substr(i, 6) == ".input")
{
s.replace(i, 6, ".output");
}

if (s.substr(i, 5) == ".data")
{
s.replace(i, 5, ".output");
}


else
{
s.append(".output");
}
break;
}

cout << "output file name: " << s;

return 0;
}



The problem is that if I input something like "file.in", it prints out "file.in.output". Whats happening here?
eww sorry for the ugly formatting
use code tags to avoid ugly formatting [code] [/code].

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
#include <iostream>
#include <string>

using namespace std;

int main()
{
	string s;
	cout << "enter name: " << endl;
	cin >> s;

	for (int i = 0; i < s.length(); i++)
	{
		if (s.substr(i, 3) == ".in")
		{
			s.replace(i, 3, ".output");
		}

		if (s.substr(i, 6) == ".input")
		{
			s.replace(i, 6, ".output");
		}

		if (s.substr(i, 5) == ".data")
		{
			s.replace(i, 5, ".output");
		}
		else
		{
			s.append(".output");
		}
		break;
	}

	cout << "output file name: " << s;

	return 0;
}


The break; will always happen so the loop will only run once. The else part will always run if s.substr(i, 5) == ".data" is false. You probably want to use else if to make it work properly.
Last edited on
else if as opposed to just the else at the end of the loop?
No I mean like this
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
if (s.substr(i, 3) == ".in")
{
	s.replace(i, 3, ".output");
}
else if (s.substr(i, 6) == ".input")
{
	s.replace(i, 6, ".output");
}
else if (s.substr(i, 5) == ".data")
{
	s.replace(i, 5, ".output");
}
else
{
	s.append(".output");
}
I did that, but it seems to be stuck in the loop. I'll input the file name, but it won't return a name. That's why I put the break; at the end of the loop.

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
#include<iostream>
#include<string>

using namespace std;

int main()
{
  string s;
  cout << "enter name: " << endl;
  cin >> s;

  for (int i = 0; i < s.length(); i++)
    {
      if (s.substr(i, 3) == ".in")
	{ 
	  s.replace(i, 3, ".output");
	}
   
      else if (s.substr(i, 6) == ".input")
	{
	  s.replace(i, 6, ".output");
	}
   
      else if (s.substr(i, 5) == ".data")
	{
	  s.replace(i, 5, ".output");
	}
    
      else 
	{
	  s.append(".output");
	}
      
      
     }
 
  cout << "output file name: " << s;

 return 0;
  }

It's getting stuck because every loop iteration you make the string longer so you will never reach the end of the string.
Are you sure you should not handle all possible file extensions? If I were to do it for all file extensions I would replace the loop with something like s = s.substr(0, s.find('.')) + ".output";
I was thinking about something like that, where I would use the find function to find the period character. What if the input has no extension, though? Adding the + ".output" would take care of that, no?
Last edited on
yes it should work with or without extension.
Okay, that seemed to work. Thank you! Just out of curiosity, though: Would there be a way to end the loop after checking through the string once, with out using break; ?
If you only want to do it once, you don't need a loop :) Also, if the files ends in ".input", it looks like the code will execute the first if condition "if s == '.in'", and you'll wind up with .outputput. A better strategy here is to find the actual extension in its entirety. Start at the end of the string, and look backwards for a "." character; you can iterate like you've been doing, or use the stl string functions. Then use that location to the end of the string - that should be your extension. Last, I believe your string comparison isn't actual string comparison, it's pointer comparison. You need to use the strcmp (or stricmp) functions.
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
int _tmain(int argc, _TCHAR* argv[])
{

	string s ,str1;
	  cout << "enter name: " << endl;
	  cin >> s;
	  size_t found = 0 ; 


		if (found  = s.find("."))
		{ 
			str1 = s.substr(found) ;
			if( str1 == ".in" )
				s.replace( found , 7 , ".output", 7);
			if( str1 == ".input" )
				s.replace( found , 7 , ".output", 7);
			if( str1 == ".data" )
				s.replace( found , 7 , ".output", 7);
			
		

	}
   
		
  cout << "output file name: " << s;
	return 0;
}
Last edited on
Last, I believe your string comparison isn't actual string comparison, it's pointer comparison

operator== has been overloaded for std::string so nothing wrong with his string comparisons.
Topic archived. No new replies allowed.