Combine strings in C++ to rename a file to present date - c++

I'm new to C++. I'm trying to write a small program that will take a .txt file from my desktop, sort it in a folder and rename it to current date.
My idea is in combining three strings, first string is a direction to the main directory where I want to move the file, second string is the name of the month in my native language and the third string is the string that represents the date in dd-mm.txt format.
#include <iostream>
#include <filesystem>
#include <ctime>
using namespace std;
int main() {
int result;
std::time_t t = std::time(0);
std::tm* now = std::localtime(&t);
char date_string[100];
strftime(date_string, 50, "\\%e-%m.txt", now);
string mnths[12] = { "Januar", "Februar","Mart","April","Maj","Jun","Jul","Avgust","Septembar","Oktobar","Novembar","Decembar" };
char strt[] = "C:\\Users\\B\\Desktop\\New.txt";
char fnsh[] = "C:\\Users\\B\\Desktop\\Journal\\2020\\"+ mnths[date_string[month]]+ date_string;
result = rename(strt, fnsh);
if (result == 0)
puts("File successfully renamed");
else
perror("Error renaming file");
return 0;
};
For the second string, in case of April for example, I want to get the fourth value in the mnths array. I've tried a mishmash of solutions looking up online but now I'm lost and need help. Most notable error is "Expression must have integral or unscoped enum type" and I've googled it but I still can't understand completely how it relates to my problem and how I can fix it. Thank you.

Related

C++ cannot name txt file after current sytem time and date

Hi im having issue with this code i have made. It will compile but once i hit enter in the program it says this:
Unhandled exception at 0x008E8641 in Log Test.exe: 0xC0000005: Access violation reading location 0x566D846A.
Here is the code:
#include <iostream>
#include <time.h>
#include <fstream>
using namespace std;
int main() {
cin.get();
time_t Time;
Time = time(0);
string Date = __DATE__;
string LOG = Time + "_" + Date;
ofstream TEST;
TEST.open(LOG);
TEST << "This Text Should Appear Inside Of File.";
TEST.close();
cout << "Log has been Made.";
cin.get();
return 0;
}
I beleive that the problem is the time and how i tried putting it into a string but i dont see what i did doesn't work.
I would think that Time is an integer type so this:
Time + "_"
results in pointer addition so that what gets added to the string is a bad pointer to some location beyond the beginning of "_".
You see string literals like "_" actually resolve to an address (pointer). Adding an integer like Time to it simple makes it point elsewhere in memory.
First you need to convert your Time to a string.
I happen to have this code laying around that may work for you:
std::string get_stamp()
{
time_t t = std::time(0);
char buf[sizeof("YYYY-MM-DD HH-MM-SS")];
return {buf, std::strftime(buf, sizeof(buf), "%F %H-%M-%S", std::localtime(&t))};
}
Note: Using std::localtime is not threas-safe.
If you enabled compiler warnings, it should have screamed at you about this line:
string LOG = Time + "_" + Date;
Here, Time is being converted to a pointer, and you're getting undefined behaviour. For a not completely C++ solution, I recommend this simple approach:
time_t t = time(0);
struct tm ttm;
localtime_r( &t, &ttm );
char timestamp[20]; // actually only need 17 chars plus terminator.
sprintf_s( timestamp, sizeof(timestamp), "%04d-%02d-%02d_%02d%02d%02d",
ttm.tm_year + 1900, ttm.tm_mon + 1, ttm.tm_day, ttm.tm_hour, ttm.tm_min, ttm.tm_sec );
string logfilename = string(timestamp) + ".log";
ofstream logfile( logfilename.c_str() );
Note that localtime_r is not completely portable. On windows, use localtime_s, which unfortunately also reverses the order of the arguments.

C++ - How to check if today's date is an a string?

I have a C++ application I'm developing where I just need to check if the current day's date is in a char array, specifically in the format "2015-05-10". I'm pretty new to C++ coming over from PHP where it is very easy to do, but I'm struggling trying to find a good method in C++. This needs to be automated as the script runs daily on a cron job. So the process is:
If (today's date is in char array) {
do this }
else {
do nothing
}
Edit: I am obviously useless at expressing my problems, sorry!
My main issues are:
How do I get the current day's date in a nice simple string in this format - 2015-05-10
How do I then check if a char array I have stored (which I know contains a date amongst some other text) contains the current day's date (which I will, when I know how, have stored as a string).
If I understood correctly, your first want to convert the current date to the format yyyy-mm-dd and then search for the string in another string.
For the first question, you may refer to How to get current time and date in C++? where there are multiple solutions given.
For the second part of the question, if you are using strings, you should use the find (http://www.cplusplus.com/reference/string/string/find/) method and if you are using char arrays, you could use the C strstr (http://www.cplusplus.com/reference/cstring/strstr/) method.
Here's what I tried:
#include <iostream>
#include <string>
#include <cstdio>
#include <ctime>
#include <cstring>
time_t now = time(0);
struct tm tstruct;
char buf[100];
tstruct = *localtime(&now);
strftime(buf, sizeof(buf), "%Y-%m-%d", &tstruct);
//char arrays used
char ch_array[] = "This is the received string 2015-05-10 from server";
char * pch;
pch = strstr(ch_array, buf);
if (pch != nullptr)
std::cout << "Found";
//string used
std::string str("This is the received string 2015-05-10 from server");
std::size_t found = str.find(buf);
if (found != std::string::npos)
std::cout << "date found at: " << found << '\n';

Want to read important double value at the end of line of istream C++

I'm trying to read in a large matrix calculated from a text file for a finite element code. The matrix is spatially dependent though and thus I need to be able to conveniently organize the data. The outside source that calculated the values for the matrix was kind enough to put the following lines at the top of the text file
No. activity levels : 3
No. pitch-angles : 90
No. energies : 11
No. L-shells : 10
Which basically tell me the number of positions the matrix is known at. I want to be able to easily pick out these values because it will allow me to preallocate the size of the matrix, as well as know immediately how much I need to interpolate for values not given by this text file. I am trying to do that with the following code
#include<iostream>
#include<fstream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<vector>
using namespace std;
int main(){
string diffusionTensorFileName = "BAS_drift_averaged_chorus_kp.txt";
string sline;
int alphaSize=0;
ifstream diffusionTensorFile(diffusionTensorFileName.c_str());
while(getline(diffusionTensorFile,sline)){
if(strncmp(sline.c_str(),"No. pitch-angles : 90",sline.size()-1)==0 && sline.size()-1 != 0){
alphaSize = atoi(sline.c_str());
printf("alphaSize %d \n", alphaSize);
vector<double> alpha(alphaSize);
}
}
}
atoi of course doesn't work very well, and I can't seem to get strtod or any of those functions to work either. Any thoughts? I'm also open to this being the completely wrong way to do this and alternate suggestions on how to proceed.
I think the easiest way would be to use the scan_is method of the std::ctype facet imbued in the streams locale. Its job is to search for first character that matches a given classification and return a pointer to it. We'll take the result of that call and use std::stoi (C++11) to parse it into an integer.
std::locale loc(diffusionTensorFile.getloc());
auto& f = std::use_facet<std::ctype<char>>(loc);
while (std::getline(diffusionTensorFile, sline))
{
const char* begin = sline.front(),
end = sline.back() + 1;
const char* result;
if ((result = f.scan_is(f.digit, begin, end)) != end)
{
alphaSize = std::stoi(result);
// do something with alphaSize
}
}
Live Demo

vector subscript out of range C++ (substring)

So I'm having this problem with substrings and converting them into integers. This will probably be an easy-fix but I'm not managing to find the answer.
So I receive this string "12-12-2012" and i want to split it, convert into integers and call the modifications methods like this:
string d = (data.substr(0,data.find("-")));
setDia(atoi(d.c_str()));
But it gives me the error mentioned in the title when I try to comvert into an integer.
EDIT:
Turns out that the string doesn't actually contain a '-' but this is really confusing since the string in the parameter results from this : to_char(s.diaInicio,'dd-mm-yyyy')
More information: I used the debugger and it's making the split correctly since the value that atoi receives is 12 (the first split). But I don't know why the VS can't convert into an integer even though the string passed is "12".
This code is not save in the sense that it fails when data does not contain a -.
Try this:
std::size_t p = data.find("-");
if(p == std::string::npos) {
// ERROR no - in string!
}
else {
std::string d = data.substr(0,p);
setDia(atoi(d.c_str()));
}
Please duplicate the problem with a very simple program. If what you say is correct, then the following program should also fail (taken from Danvil's example, and without calling the unknown (to us) setDia() function):
#include <string>
#include <cstdlib>
using namespace std;
int main()
{
string data = "12-12-2012";
std::size_t p = data.find("-");
if(p == std::string::npos) {
// ERROR no - in string!
}
else {
std::string d = data.substr(0,p);
atoi(d.c_str());
}
}

Trouble getting string to print random line from text file

I picked up this bit of code a while back as a way to select a random line from a text file and output the result. Unfortunately, it only seems to output the first letter of the line that it selects and I can't figure out why its doing so or how to fix it. Any help would be appreciated.
#include "stdafx.h"
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <string>
#include <time.h>
using namespace std;
#define MAX_STRING_SIZE 1000
string firstName()
{
string firstName;
char str[MAX_STRING_SIZE], pick[MAX_STRING_SIZE];
FILE *fp;
int readCount = 0;
fp = fopen("firstnames.txt", "r");
if (fp)
{
if (fgets(pick, MAX_STRING_SIZE, fp) != NULL)
{
readCount = 1;
while (fgets (str, MAX_STRING_SIZE, fp) != NULL)
{
if ((rand() % ++readCount) == 0)
{
strcpy(pick, str);
}
}
}
}
fclose(fp);
firstName = *pick;
return firstName;
}
int main()
{
srand(time(NULL));
int n = 1;
while (n < 10)
{
string fn = firstName();
cout << fn << endl;
++n;
}
system("pause");
}
firstName = *pick;
I am guessing this is the problem.
pick here is essentially a pointer to the first element of the array, char*, so of course *pick is of type char.. or the first character of the array.
Another way to see it is that *pick == *(pick +0) == pick[0]
There are several ways to fix it. Simplest is to just do the below.
return pick;
The constructor will automatically make the conversion for you.
Since you didn't specify the format of your file, I'll cover both cases: fixed record length and variable record length; assuming each text line is a record.
Reading Random Names, Fixed Length Records
This one is straight forward.
Determine the index (random) of the record you want.
Calculate the file position = record length * index.
Set file to the position.
Read text from file, using std::getline.
Reading Random Names, Variable Length Records
This assumes that the length of the text lines vary. Since they vary, you can't use math to determine the file position.
To randomly pick a line from a file you will either have to put each line into a container, or put the file offset of the beginning of the line into a container.
After you have your container establish, determine the random name number and use that as an index into the container. If you stored the file offsets, position the file to the offset and read the line. Otherwise, pull the text from the container.
Which container should be used? It depends. Storing the text is faster but takes up memory (you are essentially storing the file into memory). Storing the file positions takes up less room but you will end up reading each line twice (once to find the position, second to fetch the data).
Augmentations to these algorithms is to memory-map the file, which is an exercise for the reader.
Edit 1: Example
include <iostream>
#include <fstream>
#include <vector>
#include <string>
using std::string;
using std::vector;
using std::fstream;
// Create a container for the file positions.
std::vector< std::streampos > file_positions;
// Create a container for the text lines
std::vector< std::string > text_lines;
// Load both containers.
// The number of lines is the size of either vector.
void
Load_Containers(std::ifstream& inp)
{
std::string text_line;
std::streampos file_pos;
file_pos = inp.tellg();
while (!std::getline(inp, text_line)
{
file_positions.push_back(file_pos);
file_pos = inp.tellg();
text_lines.push_back(text_line);
}
}