How to read a std::string from a file in c++

  • (2 Pages)
  • +
  • 1
  • 2

17 Replies - 1631 Views - Last Post: 17 September 2015 - 03:04 PM Rate Topic: -----

#1 nordik14   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 8
  • Joined: 15-September 15

How to read a std::string from a file in c++

Posted 15 September 2015 - 05:19 PM

Hello I have a function that reads 2 integers and 1 string from a file. At this point all is ok but when I try to use the string variable as an argument in other function (load_map(std::string map_name , int tran)) that receive an std::string, an error ocurrs inside. I don't understand why?. When I write directly the std::string into the function it works. This is my code:
void load_pattern(std::string file_name){
const char * c = file_name.c_str();//converts string to const char*
/*   char *file_name;*/

   char line[80];

   int i;
   FILE *fp;
   char *token;
   char *name;
   //char *imagen_name;
   //std::string imagen_name;
   std::string search = ",";

   fp = fopen(c,"r");
   if( fp == NULL ){
        cout<<"Error while opening the file " <<c<<endl;
        exit(0);
   }
   i=0;
   while( ( fgets(line,80,fp) ) != NULL )i+=1;
   fclose(fp);

   input.N=i;
   brick=(struct Physical *)malloc(sizeof(struct Physical)*input.N);
   brickim=(struct SDL_Surface **)malloc(sizeof(SDL_Surface)*input.N);
   i=0;
   fp = fopen(c,"r");
   while(( fgets(line,80,fp ) ) != NULL ){
//-----------------------------------------------------------
        name = strtok(line, search.c_str());
        token = strtok(NULL,search.c_str());
	std::string imagen_name(strtok(NULL,search.c_str()));//<-read the string "objects/brick2.bmp" from text file
	brick[i].x=(int)atof(name);//ok
	brick[i].y=(int)atof(token);//ok
        brickim[i]=load_map(imagen_name,1);//ERROR OCURRS
	//brickim[i]=load_map("objects/brick2.bmp",1);//<-IF NOT COMMENTED it WORKS WELL WHY?
//-----------------------------------------------------------
	i+=1;
        }
   fclose(fp);
}



Here is the load_map function that basically loads an BMP image

SDL_Surface* load_map(std::string map_name , int tran ){
const char * c = map_name.c_str();//converts string to const char*

SDL_Surface *temp,*map;
Uint32 colorkey;
	cout <<"Loading bit map "<< c <<" Transparent " <<tran<<endl;
        temp = SDL_LoadBMP(c);
        if (temp == NULL){
                printf("Unable to load bitmap: %s\n", SDL_GetError());//WHEN THE ERROR OCURRS THIS IS DISPLAYED
                SDL_FreeSurface(temp);
                exit(0);
        }else{
                map = SDL_DisplayFormat(temp);
                colorkey = SDL_MapRGB( map -> format, 132, 0, 12);
                if ( tran==1 ) SDL_SetColorKey( map, SDL_SRCCOLORKEY, colorkey );
                SDL_FreeSurface(temp);
        }
                return map;
 }



I would appreciate your help with this.

Is This A Good Question/Topic? 0
  • +

Replies To: How to read a std::string from a file in c++

#2 psyking   User is offline

  • D.I.C Head
  • member icon

Reputation: 20
  • View blog
  • Posts: 173
  • Joined: 17-January 10

Re: How to read a std::string from a file in c++

Posted 15 September 2015 - 07:53 PM

What compiler are you using?
Was This Post Helpful? 0
  • +
  • -

#3 nordik14   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 8
  • Joined: 15-September 15

Re: How to read a std::string from a file in c++

Posted 15 September 2015 - 08:18 PM

View Postpsyking, on 15 September 2015 - 07:53 PM, said:

What compiler are you using?

I forgot to say that.. I'm using c++ compiler under Linux Distro kubuntu 15.04 32bit. Do you think is it related to?
Was This Post Helpful? 0
  • +
  • -

#4 psyking   User is offline

  • D.I.C Head
  • member icon

Reputation: 20
  • View blog
  • Posts: 173
  • Joined: 17-January 10

Re: How to read a std::string from a file in c++

Posted 15 September 2015 - 08:22 PM

Have you tried taking your program step-by-step through GDB to see if you can find the problem, starting from the load_pattern function?
Was This Post Helpful? 0
  • +
  • -

#5 nordik14   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 8
  • Joined: 15-September 15

Re: How to read a std::string from a file in c++

Posted 15 September 2015 - 08:54 PM

View Postpsyking, on 15 September 2015 - 08:22 PM, said:

Have you tried taking your program step-by-step through GDB to see if you can find the problem, starting from the load_pattern function?


No I haven't. But I that I've done is to print imagen_name string variable before to enter to load_map function and it seems it reads ok "objects/brick2.bmp" without "" which it's correct. However it enables a next blank line like if the string had \n. Something like objects/brick2.bmp\n. Is there any way to remove the "\n". I'm going to take some tutorias of gdb.

My text file contains something like:

1,1,objects/brick2.bmp
1,100,objects/brick2.bmp
...
Was This Post Helpful? 0
  • +
  • -

#6 Xupicor   User is offline

  • Nasal Demon
  • member icon

Reputation: 457
  • View blog
  • Posts: 1,179
  • Joined: 31-May 11

Re: How to read a std::string from a file in c++

Posted 15 September 2015 - 09:04 PM

(without looking at the code)
You don't have to guess - you can verify by comparing the last character of your string to \n, or just std::cout << '"' << str << '"';
Was This Post Helpful? 0
  • +
  • -

#7 psyking   User is offline

  • D.I.C Head
  • member icon

Reputation: 20
  • View blog
  • Posts: 173
  • Joined: 17-January 10

Re: How to read a std::string from a file in c++

Posted 15 September 2015 - 09:10 PM

View Postnordik14, on 15 September 2015 - 08:54 PM, said:

However it enables a next blank line like if the string had \n. Something like objects/brick2.bmp\n. Is there any way to remove the "\n".


fgets will add a newline character to the buffer if a newline character is read (man fgets), so you can remove the newline character by using code like this:
std::string imagen_name(strtok(NULL, search.c_str()));
std::string::reverse_iterator iter = imagen_name.rbegin();
std::remove(iter, ++iter, '\n');


This should (untested) remove it only if a newline character exists, so you don't need to use an if-statement to check.

View Postnordik14, on 15 September 2015 - 08:54 PM, said:

I'm going to take some tutorias of gdb.

Using a debugger is one of the best ways to debug your code.
Was This Post Helpful? 0
  • +
  • -

#8 nordik14   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 8
  • Joined: 15-September 15

Re: How to read a std::string from a file in c++

Posted 15 September 2015 - 09:15 PM

View PostXupicor, on 15 September 2015 - 09:04 PM, said:

(without looking at the code)
You don't have to guess - you can verify by comparing the last character of your string to \n, or just std::cout << '"' << str << '"';


Yes I've verified. The line
std::cout << '"' << imagen_name << '"';
gives me in the screen

"objects/brick2.bmp
"
so is there is any way to fix it? I've looked before but for a std::string always keeps the \n
Was This Post Helpful? 0
  • +
  • -

#9 psyking   User is offline

  • D.I.C Head
  • member icon

Reputation: 20
  • View blog
  • Posts: 173
  • Joined: 17-January 10

Re: How to read a std::string from a file in c++

Posted 15 September 2015 - 09:31 PM

View Postnordik14, on 15 September 2015 - 09:15 PM, said:

so is there is any way to fix it? I've looked before but for a std::string always keeps the \n


Check my previous post and see if that works for you.
Was This Post Helpful? 0
  • +
  • -

#10 nordik14   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 8
  • Joined: 15-September 15

Re: How to read a std::string from a file in c++

Posted 15 September 2015 - 09:43 PM

psyking It does not work. Let me show you that I code:
std::string imagen_name(strtok(NULL,search.c_str()));
std::string::reverse_iterator iter = imagen_name.rbegin();
std::remove(iter, ++iter, '\n');



The compile error is:
levels.c: In function ‘void load_pattern(std::string)’:
levels.c:444:4: error: ‘remove’ is not a member of ‘std’
std::remove(iter, ++iter, '\n');
^
levels.c:444:4: note: suggested alternative:
In file included from levels.c:1:0:
/usr/include/stdio.h:178:12: note: ‘remove’
extern int remove (const char *__filename) __THROW;
^
make: *** [levels.o] Error 1

Is there anything I did wrong?
Thanks
Was This Post Helpful? 0
  • +
  • -

#11 psyking   User is offline

  • D.I.C Head
  • member icon

Reputation: 20
  • View blog
  • Posts: 173
  • Joined: 17-January 10

Re: How to read a std::string from a file in c++

Posted 15 September 2015 - 09:44 PM

View Postnordik14, on 15 September 2015 - 09:43 PM, said:

psyking It does not work. Let me show you that I code:
std::string imagen_name(strtok(NULL,search.c_str()));
std::string::reverse_iterator iter = imagen_name.rbegin();
std::remove(iter, ++iter, '\n');



The compile error is:
levels.c: In function ‘void load_pattern(std::string)’:
levels.c:444:4: error: ‘remove’ is not a member of ‘std’
std::remove(iter, ++iter, '\n');
^
levels.c:444:4: note: suggested alternative:
In file included from levels.c:1:0:
/usr/include/stdio.h:178:12: note: ‘remove’
extern int remove (const char *__filename) __THROW;
^
make: *** [levels.o] Error 1

Is there anything I did wrong?
Thanks



You need to include the algorithm header #include <algorithm>.
Was This Post Helpful? 0
  • +
  • -

#12 nordik14   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 8
  • Joined: 15-September 15

Re: How to read a std::string from a file in c++

Posted 15 September 2015 - 09:59 PM

[/quote]


You need to include the algorithm header #include <algorithm>.
[/quote]

yes I see this compiles very well but sorry I didn't catch it. Is the iter string the new string that contains my string? I'm no familiar with this type of data std::string::reverse_iterator.
Was This Post Helpful? 0
  • +
  • -

#13 psyking   User is offline

  • D.I.C Head
  • member icon

Reputation: 20
  • View blog
  • Posts: 173
  • Joined: 17-January 10

Re: How to read a std::string from a file in c++

Posted 15 September 2015 - 10:15 PM

View Postnordik14, on 15 September 2015 - 09:59 PM, said:

yes I see this compiles very well but sorry I didn't catch it. Is the iter string the new string that contains my string? I'm no familiar with this type of data std::string::reverse_iterator.


std::string::reverse_iterator (Reference page) is a type that will allow you to traverse the string backwards. For example:
std::string Hello{ "Hello!" };
for(std::string::reverse_iterator iter = Hello.rbegin(); iter != Hello.rend(); ++iter)
{
    std::cout << *iter;
}


This will output !olleH to the console.

What std::remove(iter, ++iter, '\n'); does is goes through a few characters in your string (starting from the last, to the character just before the last) and checks if the newline character is one of the characters in your string, if it is it removes it from your string.
Was This Post Helpful? 0
  • +
  • -

#14 nordik14   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 8
  • Joined: 15-September 15

Re: How to read a std::string from a file in c++

Posted 15 September 2015 - 10:35 PM

psyking you have helped me too much but sadly it seems not to work yet and I thank you. I still have the \n at the end and when I print it I can verify because cout<<"-"<<imagen_name<<"-";
gives me:

-objects/brick2.bmp
-Unable to load bitmap: Couldn't open objects/brick2.bmp

There is still a difference when I do
brickim[i]=load_map(imagen_name,1); //It does not work



and

brickim[i]=load_map("objects/brick2.bmp",1); //It does work and why?



so this is kind of desperating. So is there another theory around it? or an alternative way to remove \n? or another way to verify if exists /n at the end of my string?. Thanks all.
Was This Post Helpful? 0
  • +
  • -

#15 psyking   User is offline

  • D.I.C Head
  • member icon

Reputation: 20
  • View blog
  • Posts: 173
  • Joined: 17-January 10

Re: How to read a std::string from a file in c++

Posted 15 September 2015 - 10:46 PM

View Postnordik14, on 15 September 2015 - 10:35 PM, said:

psyking you have helped me too much but sadly it seems not to work yet and I thank you. I still have the \n at the end and when I print it I can verify because cout<<"-"<<imagen_name<<"-";
gives me:

-objects/brick2.bmp
-Unable to load bitmap: Couldn't open objects/brick2.bmp

There is still a difference when I do
brickim[i]=load_map(imagen_name,1); //It does not work



and

brickim[i]=load_map("objects/brick2.bmp",1); //It does work and why?



so this is kind of desperating. So is there another theory around it? or an alternative way to remove \n? or another way to verify if exists /n at the end of my string?. Thanks all.


The reason that it has only been working by directly typing the location of the bitmap to load is because the newline has not been removed from the other string (which is what is trying to be fixed). So when SDL tries to find the image, it can't find a file that has a newline character in its name, which is why you are getting the error.

Try using std::remove(imagen_name.begin(), imagen_name.end(), '\n'); instead and see if it makes a difference? If it doesn't, then try this (but try it before you try this):
// compare the newline character to the last character in the string
if('\n' == imagen_name[imagen_name.size() - 1])
{
    // if it contains a newline character, take a substring of it excluding
    // the last character of the string (which is the newline character).
    imagen_name = imagen_name.substr(0, imagen_name.size() - 1);
}


Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2