Public Group

# I need help: reading string from text file in c++

This topic is 4897 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

My text file named “file.txt” Contained this: Computer Science I do this code: #include <stdio.h> #include <conio.h> #include <string.h> #include <fstream.h> #include <iostream.h> const char * filename = "file.txt"; int main () { char *buffer; long size; ifstream file (filename, ios::in|ios::binary|ios::ate); size = file.tellg(); file.seekg (0, ios::beg); buffer = new char [size]; file.read (buffer, size); file.close(); printf("%s",buffer); if( buffer=="Computer Science" ) { printf("OK"); } getch(); delete[] buffer; return 0; } But I have an output like this: Computer Science²²²²½½½½½½½½ε■ε■ And obviously the comparison doesn’t match. I need your help on how to display the text properly and to meet up the condition. Advance thanks!

##### Share on other sites
Since you sad that you use c++, use streams!

int main(){    ifstream file("filename.txt");    string text;    file >> text;    if(text == "text")      cout << "OK\n";    return 0;}

this will read in only one word ... but I don't know the funktion to read in a complet line ... something like
file.getline( text, 1024, "\n" );

and your comparison will never match because you are comparing pointers!

in C you would habe to use strcmp!

##### Share on other sites
If programming in C++, program in C++.

You can use the extraction operator to read whitespace delineated text (ie, it will grab the word "Computer" and return it to you). You can read in an entire line of formatted text using std::getline or std::istream::getline (I prefer the former). You can even read an entire file into a string using the constructor overload that takes two input iterators:
#include <fstream>#include <iostream>#include <iterator>#include <string>int main(){  using namespace std;  ifstream fin("file.txt");  //*** NOTE: The following statements are ALTERNATIVES. Reading from an input stream modifies its state,   //          such as the extraction point on a file or the contents of the read buffer. Choose ONE of   //          these methods as appropriate on an atomic scale.  // 1. read in a single word  string word;  fin >> word;  // 2. read in an entire line  string line;  getline(fin, line);  // 3. read in the whole file  string file(istream_iterator<char>(fin), istream_iterator<char>());    ...  return;}

Using C++ strings, you can perform comparisons using the intuitive equality operator (==), as already demonstrated to you by dragongame. I really suggest finding a modern introduction to and reference for C++, as what you posted is no longer C++, in so many ways. Bruce Eckel's Thinking in C++ is available online for free and quite well recommended. Try that.

Happy hacking!

##### Share on other sites
The problem is that buffer isn't getting any '\0', it doesn't even have room for it (it will if you create it with the size "size + 1". I don't know if it will be created automatically if you have room for it, or if you will have to do it manually.

But since this is C++, I would do it something like this
#include <conio.h>#include <string>#include <fstream>#include <iostream>std::string filename = "file.txt";int main (){    std::string buffer;    std::ifstream file (filename.c_str(), std::ios::in);    std::getline(file, buffer);    file.close();    std::cout << buffer;    if( buffer=="Computer Science" )    {        std::cout << "OK";    }    getch();    return 0;}

It makes it a bit easier. In addition, it is almost only standard C++ things (conio.h (and getch() isn't).

##### Share on other sites
OK I have to modified my post like this Getting info from text file in C/C++.

Actually I’m trying to get into this kind of coding
My file Collision.txt contained this data:

FaceCount: 3
TotalVertices: 9

Face1:
V1( 1.0, 1.0, 1.0 );
V2( 1.5, 1.5, 1.5 );
V3( 2.0, 2.0, 2.0 );

Face2:
V1( 3.0, 3.0, 3.0 );
V2( 3.5, 3.5, 3.5 );
V3( 3.0, 3.0, 3.0 );

Face3:
V1( 4.0, 4.0, 4.0 );
V2( 4.5, 4.5, 4.5 );
V3( 4.0, 4.0, 4.0 );

I’m trying to read the collision.txt to get the information I want

ie:

int iFaceCount = //( Read the collision.txt FaceCount: 3 )
int iTotalVertices = //( Read the collision.txt TotalVertices: 9 )

##### Share on other sites
Ok i wrote a small program which read those 2 lines and assigns them to the ints you asked for. I wrote it in MSVC++ 6.0 so if you use something else you may need to tweek it.

NOTE: i've seen many people with code like "ifstream File("blah.txt",ios::in);" and this doesn't seem to work in MSVC++ 6.0 so i added some code to find the application's directory and search for the Collision.txt file in that directory.

THE CODE:
[source code=cpp]#include "stdafx.h" //for MSVC++ not needed for anything else#include <iostream> //for cout,cin#include <fstream> //for file manipulation#include <string> //for str.find(),strlen(),str.c_str()#include <afx.h> //for application path funcs (requires "Using MFC in Shared DLL" in project-->settings (alt+f7) if running off MSVC++)using namespace std;//TO READ THE APPLICATION'S PATH FOR THE FILE OPENwstring get_module_path_wide(void);string wsts(const wstring &src_string);int main(int argc, char* argv[]){	//Function level declarations	char chrLine[2000];	string strTemp, strPath; 	int iFaceCount, iTotalVertices;	//set the path for the file to be opened from	strPath=wsts(get_module_path_wide()) + "\\Collision.txt";	//open file for input	fstream inFile(strPath.c_str(),ios::in);	//check if file was found	if(!(inFile.good()))		cout<<"File not found."<<endl;	//loop til end of file	while (!(inFile.eof()))	{		//read the line of the file		inFile.getline(chrLine,2000);		strTemp=chrLine;		//if it's the facecount line		if(strTemp.find("FaceCount:") !=std::string::npos)			//pull only the number out and convert to int			iFaceCount=atoi(strTemp.substr(strTemp.find(" ")+1,strlen(strTemp.c_str())).c_str());		//if it's the facecount line		if(strTemp.find("TotalVertices:") !=std::string::npos)			//pull only the number out and convert to int			iTotalVertices=atoi(strTemp.substr(strTemp.find(" ")+1,strlen(strTemp.c_str())).c_str());	}	//disp results	cout<<"iFaceCount="<<iFaceCount<<endl;	cout<<"iTotalVertices="<<iTotalVertices<<endl;	//pause	cin.get();	return 0;}//BELOW IS TO READ THE APPLICATION'S PATH FOR THE FILE OPEN// use Unicode (wide) version of GetModuleFileNamewstring get_module_path_wide(void){	wchar_t wide_buf[65536];	wstring module_name;	if(!GetModuleFileNameW(GetModuleHandle(0), wide_buf, 65535))		return module_name;	wide_buf[65535] = L'\0';	module_name = wide_buf;	size_t pos = module_name.find_last_of(L'\\');	if(pos != string::npos)		module_name = module_name.substr(0, pos);	return module_name;}// use this function to convert from wide wstring to ASCII string if need bestring wsts(const wstring &src_string){	size_t src_len = src_string.length();	if(src_len == 0)		return "";	char *buf = new(std::nothrow) char[src_len + 1];	if(buf == 0)		return "";	wcstombs(buf, src_string.c_str(), src_len);	buf[src_len] = '\0';	string final_string = buf;	if(buf != 0)		delete [] buf;	return final_string;}

Hope I helped.
-Lordoftools

##### Share on other sites
Like Oluseyi said: "If programming in C++, program in C++!

Do not use printf, fscanf, char* etc... well not by default. You can use them but only when you have considered the default alternative.

You didn't say so but I assume that your ultimate goal is to actually read in the faces and vertices, right? I inlined the code not for performance reasons, but to make it easier to post on the forum. In real life you would want to break it up into header and source files as appropriate.

struct Vertex{    float x,y,z;    Vertex():x(0.0f),y(0.0f),z(0.0f){}    Vertex(float x_, float y_, float z_):x(x_),y(y_),z(z_){}        //here is the key part    istream& operator>>(istream& stream, Vertex& v)    {        string format;        stream>>format; //strips out the "V1(" part of the file        stream>>v.x; //reads the data straight into v.x! no casting necessary!        stream>>format; //strips out the ","        stream>>v.y;        stream>>format; //strips out the ","        stream>>v.z        stream>>format; //strips the ");"        return stream;    }};struct Face{    Vertex a,b,c;   //put some constructors here too   //ok here is the key part, just like above    istream& operator>>(istream& stream, Face& f)    {        string format;        stream>>format;//strips out "Face1:"        stream>>f.a; //reads in the vertex straight to f.a!        stream>>f.b;        stream>>f.c;        return stream;    }}//ok now the result of all the hard work:int main(){    ifstream fin("Collision.txt");    vector<Face> faces;    Face f;    while(fin>>f)        faces.push_back(f);}

unless I made mistakes, the code reads in all of the faces and vertices properly. If you want to know how many faces you have just call faces.size(), if you want to know how many vertices just multiply that number by 3.

[Edited by - Glak on August 25, 2005 7:10:07 PM]

##### Share on other sites
Very informative post glak!

But going back to the very first post, i noticed 'size' was being created, but not initialized to any value. Therefore, size could be any arbitrary value, and as such, it was reading in from the stream more characters than were there. Though you could easily fix it by simply initializing size to a number, it is much better to use streams.

• ### What is your GameDev Story?

In 2019 we are celebrating 20 years of GameDev.net! Share your GameDev Story with us.

• 13
• 10
• 9
• 35
• 16
• ### Forum Statistics

• Total Topics
634125
• Total Posts
3015670
×