For some reason, I can't write anything to a .PGM file. The following code compiles without errors but nothing is written to the .PGM file it creates. I'm fairly new to C++ and pretty unfamiliar with working with strings in this syntax.
#include <iostream>
#include <iomanip>
#include <fstream>
#include <cstring>
#include <sstream>
int main(){
// Initialize variables.
const int ncols = 30;
const int nrows = 20;
const int maxval = 255;
std::string filename;
// Prompt user for filename.
std::cout << "What would you like to name the file of the PGM image? Please include .PGM at the end of your name." << std::endl;
// Uses getline() function to retrieve input from user into a string.
std::getline(std::cin, filename);
// Creates output stream object to use with managing the file.
std::ofstream fileOut(filename.c_str(),std::ios_base::out
|std::ios_base::binary
|std::ios_base::trunc
);
fileOut.open(filename.c_str());
fileOut << "P2" << " " << ncols << " " << nrows << " " << maxval << "\n";
fileOut.close();
}
I know there is another SO question similar to this one, but I used that answer to get here. I can't even get it to write the header part and that's not even the point of the assignment. Can anyone help?
Related
I have a C++ program that takes a directory, like "D:\P4Test", and attempts to tell me how many bytes are in each subfolder and file within that directory. The code I currently have looks like this:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
#include <string>
#include <sys/stat.h>
#include <fcntl.h>
#include <cstdint>
#include <sstream>
#include <filesystem>
using namespace std;
namespace fs = std::filesystem;
using namespace std::filesystem;
int main()
{
string path = "D:\\P4Test";
for (const auto& entry : directory_iterator(path)) {
cout << entry.path() << std::endl;
uintmax_t fsize = file_size(entry.path());
cout << " ||| " << fsize << endl;
}
}
Yes, it has a lot of unnecessary includes and such, but that's for future things.
When I run this code, I don't get what I want. Here's a picture of what's in that directory, and the output.
As you can see, the output looks good, but it does not give me the bytes for what's in the folders called "Two" & "Three".
Both folders have a text file in them that's 5 bytes, but they report back 0.
Can anyone help me figure out why, and show me how to make the folders show their bytes, or direct me to where I can figure this out?
It looks like you are trying to do a recursive file size check, but you do not actually recurse into the directories. 1 way to do this is to stasrt with a function gets all of the file sizes:
void folder_size(std::filesystem::path path) {
for (const auto& entry : directory_iterator(path)) {
cout << entry.path() << std::endl;
uintmax_t fsize = file_size(entry.path());
cout << " ||| " << fsize << endl;
}
}
Now we simply a special case to deal with if the file type is a directory, we can do this with std::filesystem::directory_entry::is_directory:
if (entry.is_directory()) {
// Handle the directory
}
So how do we handle the directory, well we have a function that we made that takes a directory path and goes through it. Lets call that:
if (std::filesystem::is_directory(entry.path())) {
folder_size(entry.path())
}
Putting it all together:
void folder_size(std::filesystem::path path) {
for (const auto& entry : directory_iterator(path)) {
cout << entry.path() << std::endl;
uintmax_t fsize = file_size(entry.path());
cout << " ||| " << fsize << endl;
if (std::filesystem::is_directory(entry.path())) {
folder_size(entry.path())
}
}
}
NOTE: All of the above is example code. No compilation check has been conducted.
I came across the following observation while working with input and output file streams and I am confused. Can anyone tell me why this happens:
I saved a txt file on my desktop by the name hello which contains the following text:
Hello my name is xyz
Next, I ran the following code:
#include <iostream>
#include <fstream>
#include <string>
int main()
{
std::fstream strm;
strm.open("C:\\Users\\SWARAJ SONAVANE\\Desktop\\hello.txt");
if (strm.fail())
{
std::cout << "failed.... :(\n";
}
//std::string p;
//strm >> p;
//std::cout << p;
strm << "random text";
}
The content of the hello.txt file after running this code was:
random textme is xyz
Now i ran the following code on the original hello.txt file
#include <iostream>
#include <fstream>
#include <string>
int main()
{
std::fstream strm;
strm.open("C:\\Users\\SWARAJ SONAVANE\\Desktop\\hello.txt");
if (strm.fail())
{
std::cout << "failed.... :(\n";
}
std::string p;
strm >> p;
std::cout << p;
strm << "random text";
}
The console printed hello but the contents of the hello.txt file remained unaltered.
Can anybody explain, what difference did reading stream into the string make?
If you want to know how streams work in C++ then you need a reference work (and maybe a tutorial as well), obviously its much more complicated than can be explained here.
The reason for what you found is the rule that if you switch from reading to writing (or vice versa) you must execute a positioning or flushing operation before you make the switch. Try the following code instead
int main()
{
std::fstream strm;
strm.open("C:\\Users\\SWARAJ SONAVANE\\Desktop\\hello.txt");
if (strm.fail())
{
std::cout << "failed.... :(\n";
}
std::string p;
strm >> p;
std::cout << p;
strm.seekp(0); // position the stream at the beginning
strm << "random text";
}
I have a program which calculates md5 hash.
I can enter the text and it will generate the md5 code.
I want to get files from computer, for example text file and generate md5 for that. The problem is that i don't know how to get the file location and assign it to variable so i can put that variable in md5 generator function.
cout << "md5 of 'grape': " << md5("example") << endl;
as you can see in the above code i enter the md5 function argument which is "example" string, so i want something like this
string foo = "C:\\Users\\User\\Downloads\\1.txt";
cout << "md5 of 'grape': " << md5(foo) << endl;
so this will calculate md5 for "C:\Users\User\Downloads\1.txt" string, but i want to calculate the 1.txt file's md5.
One way to do it is by reading the whole file into a string and passing it to md5 function like this (I assume you are using zedwood's md5):
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include "md5.h"
int main()
{
MD5 md5;
std::ifstream ifs("C:\\Users\\User\\Downloads\\1.txt", std::ios::binary);
if (ifs)
{
std::ostringstream oss;
oss << ifs.rdbuf();
std::string s(oss.str());
md5.update(s.data(), s.size());
md5.finalize();
std::cout << md5.hexdigest() << std::endl;
}
return 0;
}
This should work with non-text files too.
So I'm doing the Euler Projects and I'm storing all my Solutions in one Program. I have just started on C++, so I don't know if this is a good way to do it. Anyway, each .cpp file contains one Problem. So basically my structure is like this:
"Executer.cpp"
include <iostream>
include "other.h"
int main() {
Problem1();
Problem2();
// etc.
system("pause")
return 0;
}
"Other.h"
void Problem1();
void Problem2();
// etc.
"Problem_X.cpp" (X denotes the number of the task). I have a lot of these files.
/* PROBLEM X
*/
#include <iostream>
#include <fstream>
#include <time.h>
void ProblemX() {
time_t t1, t2;
t1 = clock();
// Code goes here
t2 = clock();
float diff((float)t2 - (float)t1);
float seconds = diff / CLOCKS_PER_SEC;
// Results
std::ofstream myFile("result.txt");
//myFile << sum;
myFile.close();
std::cout << "-------------------- Problem X -------------------" << std::endl;
std::cout << "I ran for: " << seconds << " seconds" << std::endl << std::endl;
}
Now, the Projects consist of almost 600 Problems, which means I have to create 600 files and copy the template to each of those documents. So I thought I could just make a program for doing it.
Basically, I put "Problem_X.cpp" into a text file called "standard.txt". I then wrote the following program, which i run from my int main by including the function declaration in "other.h" and calling the function from "Executer.cpp". It runs fine when copying text from one text-file to another text-file. But now (I assume since I'm trying to copy into a .cpp file) nothing happens:
#include <fstream>
#include <iostream>
#include <sstream>
void CreateNewFile(int number) // denotes the number of the problem you wish to create
{
std::string strNumber = static_cast<std::ostringstream*>(&(std::ostringstream() << Number))->str();
std::string str1 = "Problem_";
std::string str2 = ".cpp";
std::string strr;
strr.append(str1); strr.append(strNumber); strr.append(str2);
std::ofstream out(strr); //this creates it.
std::ifstream in("standard.txt");
if (!out.is_open())
{
std::cout << "ERROR: Can not open document2.txt" << std::endl;
return;
}
std::string str;
while (std::getline(in, str)) {
out << str << std::endl;
}
in.close();
out.close();
}
Does anyone have experience doing something like this? I can't find any posts on google and I am out of ideas about where to look.
The program actually runs as is is intended. It creates the new "Problem_X.cpp" files just right. They are just not imported in the VS source folder. If anyone has a quick solution for this, they are welcome to leave it in a comment here.
I want to create some text file in C++. For example: I will run a loop from 1 to 5 and create the following files:
1.txt
2.txt
3.txt
4.txt
5.txt
is it possible? I have made a sample code:
#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
main()
{
FILE *fp;
int i;
for(i=1;i<=5;i++)
{
//fp=fopen("%d.txt","r",i); //what will go here??
}
}
I am confused about what I will write inside the loop. how can I create those files?
char i;
char fileName[] = "0.txt";
for(i='1';i<='5';i++)
{
fileName[0]=i;
fp=fopen(fileName,"r"); //what will go here??
//...
}
You can use sprintf if this is too simple for your case;
Since you tag c++, I think fstream string is the thing to use.
A simple c++ example
#include <fstream>
#include <string>
using namespace std;
int main(){
string base(".txt");
for(int i=1;i<=5;++i){
ofstream(to_string(i)+base);// to_string() need c++11
}
}
If you still don't have to_string (you don't have c++11 or your compiler just don't have this) you can use this simple version for now. (better put this in your own namespace)
#include <string>
#include <sstream>
std::string to_string(int i){
std::stringstream s;
s << i;
return s.str();
}
You can use a std::stringstream to compose the file name before passing it to the std::ofstream constructor as a std::string.
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <iomanip>
int main()
{
std::cout << "How many files do you want to create? ";
int n;
std::cin >> n;
std::cout << "How many digits do you want to display? ";
int n_digits;
std::cin >> n_digits; // i.e. zeroes == 3 -> 001.txt
std::cout << "Enter a common prefix for all the files: ";
std::string prefix;
std::cin.ignore();
std::getline(std::cin, prefix); // i.e. prefix == "file" -> file001.txt
std::string ext(".txt");
for ( int i = 1; i <= n; ++i )
{ // use a stringstream to create a file names like: prefix001.txt
std::stringstream ss;
ss << prefix << std::setfill('0') << std::setw(n_digits) << i << ext;
// open the file. If not c++11 use ss.str().c_str() instead
std::ofstream file( ss.str() );
if ( !file )
{
std::cerr << "Error: failed to create file " << ss.str() << '\n';
break;
}
// write something to the newly created file
file << "This is file: " << ss.str() << "\n\nHello!\n";
if ( !file )
{
std::cerr << "Error: failed to write to file " << ss.str() << '\n';
break;
}
}
}
#include <iostream>
#include <fstream>
int main(void)
{
std::ofstream out; // you must call out.close() inside loop to be able to open another file for writting otherwise you'll get only the first one "a.txt"
std::string sFileName;
for(char c('a'); c < 'f'; c++)
{
sFileName = c;
sFileName += ".txt";
out.open(sFileName.c_str(), std::ios::out);
// std::ofstream out(sFileName.c_str(), std::ios::out); // here you are not obliged to call out.close() because the first out is not the very second and so on...
out.close(); // very important if you use the same ofstream to open another file
}
std::cout << std::endl;
return 0;
}
*** to be able to use one ostream object in opening many files you must close the precedent file to be able to open the next otherwise it fails trying creating the next one.