dcsimg
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 16

Thread: C style text file reading will refuse to get compared with std::string values.

  1. #1
    Join Date
    Jul 2017
    Posts
    78

    C style text file reading will refuse to get compared with std::string values.

    Code:
    void Shader::LoadFromFile(std::string filename, ShaderFile * shader_file)
    {
    	FILE *file;
    	char *data;
    	long size;
    
    	//Open the file for reading only.
    	file = fopen(filename.c_str(), "rb");
    
    	//Problem opengin the file.
    	if (file == NULL)
    	{
    		printf("There was an error opening the file: %s\n\n", filename.c_str());
    		printf("ERROR\n");
    		printf("------\n");
    		printf("%s\n", strerror(errno));
    		printf("\nPress ENTER to exit...");
    		getchar();
    		exit(errno);
    	}
    
    	//Get the size of the file.
    	fseek(file, 0l, SEEK_END);
    	size = ftell(file);
    	fseek(file, 0l, SEEK_SET);
    
    	//Allocate memory for the data.
    	data = (char *)malloc(sizeof(char) * (size+1));
    
    	//Read the data.
    	size_t elements = fread(data, size, 1, file);
    
    	//Something went wrong reading the file.
    	if (elements != 1)
    		printf("There was an error reading the file: %s\n", filename.c_str());
    
    	//Close the file.
    	fclose(file);
    
    	//Close the string.
    	data[size] = '\0';
    
    	//---------------Split the data into lines---------------//
    	std::vector<std::string> lines;
    	std::string line("");
    	for (unsigned int i = 0; i < size; i++)
    	{
    		//Keep adding characters until you reach the null terminate character.
    		if (data[i] != '\n') line += data[i];
    
    		//Push the string into the lines vector.
    		else
    		{
    			lines.push_back(line+"\n");
    			line = "";
    		}
    	}
    	if (line != "") lines.push_back(line+"\n");
    	//---------------Split the data into lines---------------//
    
    
    	//----------------Create The Source Codes----------------//
    	bool vertex = true;
    	for (std::string line : lines)
    	{
    		std::cout << line;
    		getchar();
    		if ( line == "#vertex\n" )
    		{
    			std::cout << "hahahahaha" << std::endl;
    			vertex = true;
    			continue;
    		}
    
    		//Change to fragment shader.
    		if (line == "#fragment\n")
    		{
    			vertex = false;
    			continue;
    		}
    
    		//Add line to vertex source code.
    		if (vertex)
    			shader_file->vertex_src += line;
    
    		//Add line to fragment source code.
    		else
    			shader_file->fragment_src += line;
    	}
    	//----------------Create The Source Codes----------------//
    
    	//Free the data.
    	free(data);
    }
    In the Create The Source Codes section in my code you can see i have two lines for debugging:
    Code:
    std::cout << line;
    getchar();
    This outputs me exactly:
    Code:
    #vertex
    with a new line at the end.

    The think is that the code:
    Code:
    if ( line == "#vertex\n" )
    		{
    			std::cout << "hahahahaha" << std::endl;
    			vertex = true;
    			continue;
    		}
    never gets true and i'm sure that the very first line is #vertex.

    I think the problem might be with reading the file, maybe some encoding stuff but I don't know about that and this is why i'm asking you.


    Also in order to not waste your time every time in such matters, is there any good online resource where i can learn how to move from c to c++?
    Generally i've notice that when i'm programming in c++ (coming from c) a lot of thinks that i'm doing in c style end to be problematic
    but when i was writing code only in c (compiling with a c compiler only not c++) i had no problems at all. I think its because i'm mixing c and c++
    stuff together.
    Last edited by babaliaris; October 9th, 2018 at 12:03 PM.

  2. #2
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    6,511

    Re: C style text file reading will refuse to get compared with std::string values.

    After
    Code:
    std::cout << line;
    add
    Code:
    std::cout << std::endl;
    
    for (const auto& ch : line)
        std::cout << "'" << (char)ch << "' " << (int)ch << " ";
    
    std::cout << endl;
    and see what is displayed. This should show each character of line first as a char within ' and then as its decimal equivalent. From this you should be able to determine the issue.

    Why use c file handling? Why not c++ file streams? Why use c memory management and not c++ managed memory?
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++17 Compiler: Microsoft VS2017 (15.9.3)

  3. #3
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    6,511

    Re: C style text file reading will refuse to get compared with std::string values.

    Also in order to not waste your time every time in such matters, is there any good online resource where i can learn how to move from c to c++?
    Generally i've notice that when i'm programming in c++ (coming from c) a lot of thinks that i'm doing in c style end to be problematic
    but when i was writing code only in c (compiling with a c compiler only not c++) i had no problems at all. I think its because i'm mixing c and c++
    stuff together.
    It's not mixing c/c++ code as such it's that although c++ is based upon c it now isn't totally c conformant. Much of c code will compile/execute ok under c++ but not all of it. It's best to treat c and c++ as 2 different languages with some similarities than c++ being a superset of c. Many things that are done a certain way in c are done differently in c++ (although in many cases the c way will still work).

    For on-line c++ guides, consider
    https://www.learncpp.com/
    https://en.cppreference.com/w/cpp/language

    I don't know of a guide for moving from c to c++.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++17 Compiler: Microsoft VS2017 (15.9.3)

  4. #4
    Join Date
    Feb 2017
    Posts
    370

    Re: C style text file reading will refuse to get compared with std::string values.

    Quote Originally Posted by babaliaris View Post
    I think the problem might be with reading the file, maybe some encoding stuff
    The end of line in Windows and DOS is encoded with both carriage return and linefeed , like \r\n.

    If that's the case you should check for "#vertex\r\n".
    Last edited by wolle; October 9th, 2018 at 05:21 PM.

  5. #5
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    19,262

    Re: C style text file reading will refuse to get compared with std::string values.

    Quote Originally Posted by babaliaris View Post
    Code:
    void Shader::LoadFromFile(std::string filename, ShaderFile * shader_file)
    {
    	...
    	if (file == NULL)
    	{
    		printf("There was an error opening the file: %s\n\n", filename.c_str());
    		printf("ERROR\n");
    		printf("------\n");
    		printf("%s\n", strerror(errno));
    		printf("\nPress ENTER to exit...");
    		getchar();
    		exit(errno);
    	}
    	...
    }
    You should not use exit() in c++ program. See:
    https://www.codeguru.com/cpp/cpp/cpp...place-exit.htm
    https://stackoverflow.com/questions/...-to-end-c-code

    Using malloc/free is not a good idea either. Use c++ new/delete instead!
    Victor Nijegorodov

  6. #6
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    6,511

    Re: C style text file reading will refuse to get compared with std::string values.

    Code:
    file = fopen(filename.c_str(), "rb");
    Why are you opening the file in binary mode - but reading it as a text file? Try opening the file in text mode ("r") so that the expected translations occur.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++17 Compiler: Microsoft VS2017 (15.9.3)

  7. #7
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    6,511

    Re: C style text file reading will refuse to get compared with std::string values.

    For coding this in c++, consider (not tried)

    Code:
    #include <fstream>
    ...
    
    bool Shader::LoadFromFile(const std::string& filename, ShaderFile * shader_file)
    {
        std::ifstream file(filename);
    
        if (!file.is_open()) {
            std::cout << "There was an error opening the file: " << filename << std::endl;
            return false;
        }
    
        bool vertex = true;
    
        for (std::string line; std::getline(file, line); ) {
            if ( line == "#vertex" ) {
                vertex = true;
                continue;
            }
    
            if (line == "#fragment") {
                vertex = false;
                continue;
            }
    
            if (vertex)
                shader_file->vertex_src += line;
    	else
                shader_file->fragment_src += line;
        }
    
        file.close();
        return true;
    }
    Last edited by 2kaud; October 10th, 2018 at 03:47 AM.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++17 Compiler: Microsoft VS2017 (15.9.3)

  8. #8
    Join Date
    Jul 2017
    Posts
    78

    Re: C style text file reading will refuse to get compared with std::string values.

    Quote Originally Posted by wolle View Post
    The end of line in Windows and DOS is encoded with both carriage return and linefeed , like \r\n.

    If that's the case you should check for "#vertex\r\n".
    LOL that worked!!! But what do you do if you want your app to be cross platform?

  9. #9
    Join Date
    Jul 2017
    Posts
    78

    Re: C style text file reading will refuse to get compared with std::string values.

    Quote Originally Posted by 2kaud View Post
    Code:
    file = fopen(filename.c_str(), "rb");
    Why are you opening the file in binary mode - but reading it as a text file? Try opening the file in text mode ("r") so that the expected translations occur.
    When i use fread i get an error for some reason in text mode...
    Last edited by babaliaris; October 10th, 2018 at 05:43 AM.

  10. #10
    Join Date
    Jul 2017
    Posts
    78

    Re: C style text file reading will refuse to get compared with std::string values.

    Quote Originally Posted by VictorN View Post
    You should not use exit() in c++ program. See:
    https://www.codeguru.com/cpp/cpp/cpp...place-exit.htm
    https://stackoverflow.com/questions/...-to-end-c-code

    Using malloc/free is not a good idea either. Use c++ new/delete instead!
    Hmmm, I didn't know about that. Is assert also bad to use? Or its ok?

  11. #11
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    6,511

    Re: C style text file reading will refuse to get compared with std::string values.

    assert() is usually only active in a debug build. In a release build it usually does nothing. It's action depends upon the macro NDEBUG. If NDEBUG is defined then assert() does nothing. See https://en.cppreference.com/w/cpp/error/assert It's not considered good practice to have active assert() statements in release build code. Expected run-time issues (such as a file not found etc) should be handled gracefully within the code. In the code of post #7, I changed the definition of the function to have a bool return value so that the calling function knows if there was a problem or not, and if there was a problem to take appropriate action (ask again for the file name, etc). This could be handled with exceptions - but not being able to open a file is not usually considered an exception. assert() is worse than exit() - as assert() calls abort()!

    See
    https://en.cppreference.com/w/cpp/utility/program/abort
    https://en.cppreference.com/w/cpp/utility/program/exit

    Use assert in debug builds to make sure the code is working properly (eg a passed pointer is not null etc) - but don't use it to handle run-time errors in release code.

    Code as if exit() and abort() don't exist.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++17 Compiler: Microsoft VS2017 (15.9.3)

  12. #12
    Join Date
    Jul 2017
    Posts
    78

    Re: C style text file reading will refuse to get compared with std::string values.

    Quote Originally Posted by 2kaud View Post
    assert() is usually only active in a debug build. In a release build it usually does nothing. It's action depends upon the macro NDEBUG. If NDEBUG is defined then assert() does nothing. See https://en.cppreference.com/w/cpp/error/assert It's not considered good practice to have active assert() statements in release build code. Expected run-time issues (such as a file not found etc) should be handled gracefully within the code. In the code of post #7, I changed the definition of the function to have a bool return value so that the calling function knows if there was a problem or not, and if there was a problem to take appropriate action (ask again for the file name, etc). This could be handled with exceptions - but not being able to open a file is not usually considered an exception. assert() is worse than exit() - as assert() calls abort()!

    See
    https://en.cppreference.com/w/cpp/utility/program/abort
    https://en.cppreference.com/w/cpp/utility/program/exit

    Use assert in debug builds to make sure the code is working properly (eg a passed pointer is not null etc) - but don't use it to handle run-time errors in release code.

    Code as if exit() and abort() don't exist.
    Thank you! I didn't know about all these things but they make sense!

  13. #13
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    6,511

    Re: C style text file reading will refuse to get compared with std::string values.

    Like I said in post #3, c++ isn't c!
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++17 Compiler: Microsoft VS2017 (15.9.3)

  14. #14
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    6,511

    Re: C style text file reading will refuse to get compared with std::string values.

    Quote Originally Posted by babaliaris View Post
    When i use fread i get an error for some reason in text mode...
    The error occurs here
    Code:
    //Read the data.
    	size_t elements = fread(data, size, 1, file);
    
    	//Something went wrong reading the file.
    	if (elements != 1)
    		printf("There was an error reading the file: %s\n", filename.c_str());
    This is because you are reading an item of length size from the file. However, in text mode \r\n is converted to just \n (which is what is required). So the number of chars actually read is less than the number specified for the item - hence a full item hasn't been read as far as fread() is concerned so elements is set to 0, hence the test against 1 fails. If you are attempting to read the whole file with one fread() as here in text mode, then you can't do a test on the return value of fread(). You can only test that the file is at eof - which it will be if no issues reading the file have occurred. Hence

    Code:
    fread(data, size, 1, file);
    
    if (!feof(data))
        std::cout << There was an error reading the file: " << filename << std::endl;
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++17 Compiler: Microsoft VS2017 (15.9.3)

  15. #15
    Join Date
    Jul 2017
    Posts
    78

    Re: C style text file reading will refuse to get compared with std::string values.

    Quote Originally Posted by 2kaud View Post
    The error occurs here
    Code:
    //Read the data.
    	size_t elements = fread(data, size, 1, file);
    
    	//Something went wrong reading the file.
    	if (elements != 1)
    		printf("There was an error reading the file: %s\n", filename.c_str());
    This is because you are reading an item of length size from the file. However, in text mode \r\n is converted to just \n (which is what is required). So the number of chars actually read is less than the number specified for the item - hence a full item hasn't been read as far as fread() is concerned so elements is set to 0, hence the test against 1 fails. If you are attempting to read the whole file with one fread() as here in text mode, then you can't do a test on the return value of fread(). You can only test that the file is at eof - which it will be if no issues reading the file have occurred. Hence

    Code:
    fread(data, size, 1, file);
    
    if (!feof(data))
        std::cout << There was an error reading the file: " << filename << std::endl;
    Thank you!!!!!

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width




On-Demand Webinars (sponsored)