I'm trying to write a string into a file, but I don't know how to do it, I have tried to use wstring instead of string in my randomString() string function, and other things just to write a string to a file.
The if condition is checking if file is created, and if yes, write to it.
fopen is used to open the file, path1 variable is the path to my file, and the "w" is equal to write.
randomString() is a string function.
char buffer[100] = { randomString() };
FILE* file;
file = fopen(path1, "w");
if (file) {
fwrite(buffer, sizeof(char), sizeof(buffer), file);
fclose(file);
}
return;
If you're using a new-ish compiler you can try std::filesystem
#include <iostream>
#include <fstream>
#include <filesystem>
namespace fs = std::filesystem;
int main() {
auto directoryToWriteTo = fs::current_path(); // returns a fs::path object
std::ofstream fileStream(directoryToWriteTo.string() + "/nameOfYourFile.txt");
if(fileStream.is_open())
fileStream << "Whatever string you want to write to a file\n";
}
std::filesystem isn't needed for writing to one file, but it does make things like iterating over all files in a directory easy, as adapted from the cppreference.com examples.
#include <fstream>
#include <iostream>
#include <filesystem>
namespace fs = std::filesystem;
int main() {
auto directoryToTraverse = fs::current_path();
for(auto& p: fs::directory_iterator(directoryToTraverse)){
if(fs::is_regular_file(p)){
std::ofstream tmpStream(p,std::ios_base::app); //open file in append mode
tmpStream << "Append a string to each regular file in your directory\n";
}
}
}
It also allows one to change file permissions programmatically with standard c++.
If you are just trying to print out to a file the contents of a string, using fwrite, then you need to do something like the following
std::string str = randomString();
if ( file ) {
fwrite( str.c_str(), sizeof( char ), str.size(), file );
fclose( file );
}
Since fwrite expects the first parameter to be void *, an std::string is not compatible; however, a char * is. By calling .c_str() on the string, you would have a char * to work with. The second parameter is the size of the type, which for a std::string is char, so sizeof( char ) gives the size (which is 1). The third parameter is the count (number of characters to write), which can easily be gotten from str.size().
Related
I'm trying to determine how big a file i'm reading is in bytes so I used Fseek to jump to the end and it triggered the error: file.exe has triggered a breakpoint.
Heses the code:
FileUtils.cpp:
#include "FileUtils.h"
namespace impact {
std::string read_file(const char* filepath)
{
FILE* file = fopen(filepath, "rt");
fseek(file, 0, SEEK_END);
unsigned long length = ftell(file);
char* data = new char[length + 1];
memset(data, 0, length + 1);
fseek(file, 0 ,SEEK_SET);
fread(data, 1, length, file);
fclose(file);
std::string result(data);
delete[] data;
return result;
}
}
FileUtils.h:
#pragma once
#include <stdio.h>
#include <string>
#include <fstream>
namespace impact {
std::string read_file(const char* filepath);
}
If more info is required just ask me for it I would be more than happy to provide more!
You are doing this in the C way, C++ has much better (in my opinion) ways of handling files.
Your error looks like it may be caused because the file didn't open correctly (you need to check if file != nullptr).
To do this in C++17 you should use the standard library filesystem
(Note: You can also do this with C++11 experimental/filesystem using std::experimental::filesystem namespace)
Example:
std::string read_file(const std::filesystem::path& filepath) {
auto f_size = std::filesystem::file_size(filepath);
...
}
Additionally to read a file in C++ you do not need to know the size of the file. You can use streams:
std::string read_file(const std::filesystem::path& filepath) {
std::ifstream file(filepath); // Open the file
// Throw if failed to open the file
if (!file) throw std::runtime_error("File failed to open");
std::stringstream data; // Create the buffer
data << file.rdbuf(); // Read into the buffer the internal buffer of the file
return data.str(); // Convert the stringstream to string and return it
}
As you can see, the C++ way of doing it is much shorter and much easier to debug (helpful exceptions with descriptions are thrown when something goes wrong)
I'm trying to read file, which contains Cyrillic characters in their path, and got ifstream.is_open() == false
This is my code:
std::string ReadFile(const std::string &path) {
std::string newLine, fileContent;
std::ifstream in(path.c_str(), std::ios::in);
if (!in.is_open()) {
return std::string("isn't opened");
}
while (in.good()) {
getline(in, newLine);
fileContent += newLine;
}
in.close();
return fileContent;
}
int main() {
std::string path = "C:\\test\\документ.txt";
std::string content = ReadFile(path);
std::cout << content << std::endl;
return 0;
}
Specified file exists
I'm trying to find solution in google, but I got nothing
Here is links, which I saw:
I don't need wstring
The same as previous
no answer here
is not about C++
has no answer too
P.S. I need to get file's content in string, not in wstring
THIS IS ENCODING SETTINGS OF MY IDE (CLION 2017.1)
You'll need an up-to-date compiler or Boost. std::filesystem::path can handle these names, but it's new in the C++17 standard. Your compiler may still have it as std::experimental::filesystem::path, or else you'd use the third-party boost::filesystem::path. The interfaces are pretty comparable as the Boost version served as the inspiration.
The definition for std::string is std::basic_string, so your Cyrillic chararecters are not stored as intended. Atleast, try to use std::wstring to store your file path and then you can read from file using std::string.
First of all, set your project settings to use UTF-8 encoding instead of windows-1251. Until standard library gets really good (not any time soon) you basically can not rely on it if you want to deal with io properly. To make input stream read from files on Windows you need to write your own custom input stream buffer that opens files using 2-byte wide chars or rely on some third-party implementations of such routines. Here is some incomplete (but sufficient for your example) implementation:
// assuming that usual Windows SDK macros such as _UNICODE, WIN32_LEAN_AND_MEAN are defined above
#include <Windows.h>
#include <string>
#include <iostream>
#include <system_error>
#include <memory>
#include <utility>
#include <cstdlib>
#include <cstdio>
static_assert(2 == sizeof(wchar_t), "wchar_t size must be 2 bytes");
using namespace ::std;
class MyStreamBuf final: public streambuf
{
#pragma region Fields
private: ::HANDLE const m_file_handle;
private: char m_buffer; // typically buffer should be much bigger
#pragma endregion
public: explicit
MyStreamBuf(wchar_t const * psz_file_path)
: m_file_handle(::CreateFileW(psz_file_path, FILE_GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL))
, m_buffer{}
{
if(INVALID_HANDLE_VALUE == m_file_handle)
{
auto const error_code{::GetLastError()};
throw(system_error(static_cast< int >(error_code), system_category(), "::CreateFileW call failed"));
}
}
public:
~MyStreamBuf(void)
{
auto const closed{::CloseHandle(m_file_handle)};
if(FALSE == closed)
{
auto const error_code{::GetLastError()};
//throw(::std::system_error(static_cast< int >(error_code), system_category(), "::CloseHandle call failed"));
// throwing in destructor is kinda wrong
// but if CloseHandle returned false then our program is in inconsistent state
// and must be terminated anyway
(void) error_code; // not used
abort();
}
}
private: auto
underflow(void) -> int_type override
{
::DWORD bytes_count_to_read{1};
::DWORD read_bytes_count{};
{
auto const succeeded{::ReadFile(m_file_handle, addressof(m_buffer), bytes_count_to_read, addressof(read_bytes_count), nullptr)};
if(FALSE == succeeded)
{
auto const error_code{::GetLastError()};
setg(nullptr, nullptr, nullptr);
throw(system_error(static_cast< int >(error_code), system_category(), "::ReadFile call failed"));
}
}
if(0 == read_bytes_count)
{
setg(nullptr, nullptr, nullptr);
return(EOF);
}
setg(addressof(m_buffer), addressof(m_buffer), addressof(m_buffer) + 1);
return(m_buffer);
}
};
string
MyReadFile(wchar_t const * psz_file_path)
{
istream in(new MyStreamBuf(psz_file_path)); // note that we create normal stream
string new_line;
string file_content;
while(in.good())
{
getline(in, new_line);
file_content += new_line;
}
return(::std::move(file_content));
}
int
main(void)
{
string content = MyReadFile(L"C:\\test\\документ.txt"); // note that path is a wide string
cout << content << endl;
return 0;
}
Change your code to use wstring and save your file using Unicode encoding (non UTF8 one, use USC-2, UTF16 or something like that). MSVC has non-standard overload specifically for this reason to be able to handle non-ascii chars in filenames:
std::string ReadFile(const std::wstring &path)
{
std::string newLine, fileContent;
std::ifstream in(path.c_str(), std::ios::in);
if (!in)
return std::string("isn't opened");
while (getline(in, newLine))
fileContent += newLine;
return fileContent;
}
int main()
{
std::wstring path = L"C:\\test\\документ.txt";
std::string content = ReadFile(path);
std::cout << content << std::endl;
}
Also, note corrected ReadFile code.
Can someone tell me what am i doing wrong here i am getting an error saying getline() not declared in this scope.........any help would be appreciated.
no matching function for call to getline(char**, size_t*, FILE*&)
#include<iostream>
#include<fstream>
#include<string>
using namespace std;
char *s;
int main(int argc, char *argv[])
{
FILE* fd = fopen("input.txt", "r");
if(fd == NULL)
{
fputs("Unable to open input.txt\n", stderr);
exit(EXIT_FAILURE);
}
size_t length = 0;
ssize_t read;
const char* backup;
while ((read = getline(&s, &length, fd) ) > 0)
{
backup = s;
if (A() && *s == '\n')
{
printf("%sis in the language\n", backup);
}
else
{
fprintf(stderr, "%sis not in the language\n", backup);
}
}
fclose(fd);
return 0;
}
You'll need to use C++ style code in order to use getline in a cross platform way.
#include <fstream>
#include <string>
using namespace std;
std::string s;
bool A() { return true; }
int main(int argc, char *argv[])
{
ifstream myfile("input.txt");
if(!myfile.is_open())
{
fprintf(stderr, "Unable to open input.txt\n");
return 1;
}
size_t length = 0;
size_t read;
std::string backup;
while (getline(myfile, s))
{
backup = s;
if (A() && s == "\n")
{
printf("%s is in the language\n", backup.c_str());
}
else
{
fprintf(stderr, "%s is not in the language\n", backup.c_str());
}
}
return 0;
}
What are you trying to do with getline(&s, &length, fd)? Are you trying to use the C getline?
Assuming you have opened the file correctly, in c++ your getline should look something like this: getline(inputStream, variableToReadInto, optionalDelimiter).
You didn't include <stdio.h> but you did include <fstream>. Maybe use ifstream fd("input.txt");
What's A()
If you ARE trying to use the C getline, the using namespace std may be interfering
Why are you using printf and fprintf and not cout << xxxxxx and fd << xxxxxx
You seem to be a bit confused with various getline function signatures.
The standard C++ std::getline signature is
template< class CharT, class Traits, class Allocator >
std::basic_istream<CharT,Traits>& getline( std::basic_istream<CharT,Traits>& input,
std::basic_string<CharT,Traits,Allocator>& str,
CharT delim );
It takes an input stream object, a string and a character delimiter (there's an overload without the delimiter too).
The posix getline signature is
ssize_t getdelim(char **lineptr, size_t *n, int delim, FILE *stream);
with the delimiter optional again.
now in your code your passing arguments as if calling the posix version without delimiter. If you want to use the standard one you'll have to change the arguments (i.e. istream object instead of FILE*). I don't know if the posix one is even available for you, since posix is different from any C++ standard.
Note that the fputs, FILE*, fprintf are C filehandling functions, not the C++ ones.
I have a problem with the following code:
#include <iostream>
#include <stdio.h>
#include "ISBNPrefix.h"
using namespace std;
int main() {
FILE* file = NULL;
int area = 0, i = 0;
long s;
file = open("swagger.txt");
fscanf(file, "%ld", &s);
cout << s << endl;
}
and here's ISBNPrefix.cpp:
#include <iostream>
#include <stdio.h>
#include "ISBNPrefix.h"
using namespace std;
FILE* open(const char filename[]) {
FILE* file = NULL;
file = fopen("filename", "r");
if (file != NULL)
return file;
else return NULL;
}
my ISBNPrefix.h
FILE* open (const char filename[]);
And the content of swagger.txt is: 123456789
When I try to run it to test if it copies the 123456789 into my variable i get a segmentation fault!
You have problem in your function for opening a file:
FILE* open(const char filename[]) {
FILE* file = NULL;
file = fopen("filename", "r"); <-- here
it should be file = fopen(filename, "r");
Also you designed open function to return NULL if there is no file, but then you don't check its return value once you call it:
file = open("swagger.txt");
if (file == NULL) ... <-- you should check the return value
fscanf(file, "%ld", &s);
Also note that fopen and fscanf are C-style functions. Since you are using C++, there are other more convenient means how to read data from a file. Have a look at std::ifstream. Also when you work with C headers in C++, you should include their C++ wrappers: cstdio, cstdlib, etc.
You need fopen for a start. Where does ISBNPrefix.cpp come into the picture?
I was wondering if there is a way to output the hexdump or raw data of a file to txt file.
for example
I have a file let's say "data.jpg" (the file type is irrelevant) how can I export the HEXdump (14ed 5602 etc) to a file "output.txt"?
also how I can I specify the format of the output for example, Unicode or UTF?
in C++
You can use a loop, fread and fprintf: With read you get the byte-value of the bytes, then with fprintf you can use the %x to print hexadecimal to a file.
http://www.cplusplus.com/reference/clibrary/cstdio/fread/
http://www.cplusplus.com/reference/clibrary/cstdio/fprintf/
If you want this to be fast you load whole machine-words (int or long long) instead of single bytes, if you want this to be even faster you fread a whole array, then sprintf a whole array, then fprintf that array to the file.
Maybe something like this?
#include <sstream>
#include <iostream>
#include <iomanip>
#include <iterator>
#include <algorithm>
int main()
{
std::stringstream buffer( "testxzy" );
std::istreambuf_iterator<char> it( buffer.rdbuf( ) );
std::istreambuf_iterator<char> end; // eof
std::cout << std::hex << std::showbase;
std::copy(it, end, std::ostream_iterator<int>(std::cout));
std::cout << std::endl;
return 0;
}
You just have to replace buffer with an ifstream that reads the binary file, and write the output to a textfile using an ofstream instead of cout.
This is pretty old -- if you want Unicode, you'll have to add that yourself.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
unsigned long offset = 0;
FILE *input;
int bytes, i, j;
unsigned char buffer[16];
char outbuffer[60];
if ( argc < 2 ) {
fprintf(stderr, "\nUsage: dump filename [filename...]");
return EXIT_FAILURE;
}
for (j=1;j<argc; ++j) {
if ( NULL ==(input=fopen(argv[j], "rb")))
continue;
printf("\n%s:\n", argv[j]);
while (0 < (bytes=fread(buffer, 1, 16, input))) {
sprintf(outbuffer, "%8.8lx: ", offset+=16);
for (i=0;i<bytes;i++) {
sprintf(outbuffer+10+3*i, "%2.2X ",buffer[i]);
if (!isprint(buffer[i]))
buffer[i] = '.';
}
printf("%-60s %*.*s\n", outbuffer, bytes, bytes, buffer);
}
fclose(input);
}
return 0;
}