String functions

Nov 28, 2011 at 6:24am
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?
Nov 28, 2011 at 6:29am
eww sorry for the ugly formatting
Nov 28, 2011 at 6:34am
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 Nov 28, 2011 at 6:35am
Nov 28, 2011 at 6:51am
else if as opposed to just the else at the end of the loop?
Nov 28, 2011 at 6:53am
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");
}
Nov 28, 2011 at 7:00am
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;
  }

Nov 28, 2011 at 7:02am
It's getting stuck because every loop iteration you make the string longer so you will never reach the end of the string.
Nov 28, 2011 at 7:12am
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";
Nov 28, 2011 at 7:22am
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 Nov 28, 2011 at 7:24am
Nov 28, 2011 at 7:26am
yes it should work with or without extension.
Nov 28, 2011 at 7:32am
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; ?
Nov 28, 2011 at 8:34am
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.
Nov 28, 2011 at 8:48am
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 Nov 28, 2011 at 8:49am
Nov 28, 2011 at 2:52pm
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.