combining strings - string

I'm trying to combine strings to input text files. My code looks like this:
`#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
using namespace std;
int main(){
int year;
string line;
string fileName;
for (int i=1880; i<2012; i++){
stringstream ss;
ss << year;
fileName = string("yob") + string(year) + string(".txt");
ifstream ifile(fileName.c_str());
getline(ifile,line);
cout << line << endl;
ifile.close();
}
}`
The text files look like "yob1880.txt" <-- that's the first text file and it goes all the way to "yob2011.txt". I want to input the text files one by one, but combining these three string types doesn't work it gives me an error saying invalid conversion from int to const char*.
Any thoughts on the problem? Thanks!

You should get it from the stringstream. You're almost there but this is what you should do instead:
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
using namespace std;
int main(){
int year;
string line;
string fileName;
for (int i=1880; i<2012; i++){
year = i; //I'm assuming this is what you meant to use "year" for
stringstream ss;
ss << year; //add int to stringstream
string yearString = ss.str(); //get string from stringstream
fileName = string("yob") + yearString + string(".txt");
ifstream ifile(fileName.c_str());
getline(ifile,line);
cout << line << endl;
ifile.close();
}
}

Related

Question about this error: ‘bdget’ was not declared in this scope

trying to figure out why I’m getting this error about ’bdget’ (when on Linux Ubuntu, info below) and how to get rid of this error, maybe you could suggest some specific steps for me to try and/or ask me to provide you some additional info about the error, thank you for any help.
error: ‘bdget’ was not declared in this scope
b_dev = bdget(st.st_rdev);
The code (for a short sample/tester program put together quickly to demonstrate the problem here to you) that produces this error is below, here’s other info: When I comment out that ‘bdget’ line, the program (seen below) compiles, otherwise it doesn’t and produces the error. I understand from other stackoverflow.com questions that using bdget requires #include <linux/fs.h>, which I’ve done here as you can see in the code below.
I think this is my first question here at stackoverflow.com, haven’t yet learned what question-related actions I need to take here at stackoverflow.com about your answers such as accept, and the steps for taking those actions, so bear with me a bit.
Regards,
Yaman Aksu,PhD
The build used this g++ version (full path: /usr/bin/g++) :
g++ (Ubuntu 7.3.0-27ubuntu1-18.04) 7.3.0 <snip>
and was simple as follows:
g++ -Wall -03 tester.cpp -o tester
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/sysmacros.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <linux/fs.h>
#define FNABS_SIZE 1024
char prog[FNABS_SIZE];
using namespace std;
int main(int argc, char *argv[])
{
int rv=0;
struct dirent *de;
struct stat st;
struct block_device *b_dev;
char direc[FNABS_SIZE], fnabs[FNABS_SIZE], fnabs_bfile[FNABS_SIZE], hd_serial[NAME_MAX], hd_model[NAME_MAX];
int status;
unsigned int maj_rdev, min_rdev;
ios::sync_with_stdio();
strcpy(prog,argv[0]); argc--;
strcpy(direc,"/dev/disk/by-id");
for (DIR *p = opendir(direc); (de=readdir(p)); ) {
if (de->d_type==DT_LNK) {
sprintf(fnabs,"%s/%s",direc,de->d_name);
cout << "[glk] Now running 'stat' on this: " << fnabs << endl;
status = stat(fnabs, &st);
cout << "[glk] 'stat' results:" << endl;
cout << "[glk]\t return value:" << status << endl;
cout << "[glk]\t st.st_rdev:" << st.st_rdev << endl;
cout << "[glk]\t st.st_dev=" << st.st_dev << endl;
cout << "[glk]\t st.st_ino=" << st.st_ino << endl;
maj_rdev = major(st.st_rdev); min_rdev = minor(st.st_rdev);
printf("[glk]\t major:minor = %u:%u\n",maj_rdev, min_rdev);
if ((st.st_mode & S_IFMT) == S_IFBLK) {
printf("[glk]\t This is a 'block device' !!\n");
}
b_dev = bdget(st.st_rdev);
}
}
}

Convert string with 6 digits before decimal to Double

I have a string with the value 788597.31 and I am converting this value to double but when I print the variable only 788597 is displayed. I have used std::stod(string) and even stringstream but everytime I get the same previous value. Can anybody help me with this?
I want to store this string value in a double varaible.
#include<iostream>
#include<string>
#include<sstream>
using namespace std;
int main()
{
string s="788597.31";
double d=stod(s);
cout<<d<<" ";
stringstream g;
double a;
g<<s; g>>a;
cout<<a;
return 0;
}
The problem is in how you are printing your result, not in the string parsing. This program:
#include <iostream>
using namespace std;
int main() {
cout << 788597.31 << endl;
return 0;
}
also prints 788597.
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
cout << setprecision(10) << 788597.31 << endl;
return 0;
}
prints 788597.31
If you want to see more than the default 6 significant digits your program needs to say so.

C++11: how to use accumulate / lambda function to calculate the sum of all sizes from a vector of string?

For a vector of strings, return the sum of each string's size.
I tried to use accumulate, together with a lambda function (Is it the best way of calculating what I want in 1-line?)
Codes are written in wandbox (https://wandbox.org/permlink/YAqXGiwxuGVZkDPT)
#include <iostream>
#include <numeric>
#include <string>
#include <vector>
using namespace std;
int main() {
vector<string> v = {"abc", "def", "ghi"};
size_t totalSize = accumulate(v.begin(), v.end(), [](string s){return s.size();});
cout << totalSize << endl;
return 0;
}
I expect to get a number (9), however, errors are returned:
/opt/wandbox/gcc-head/include/c++/10.0.0/bits/stl_numeric.h:135:39: note: 'std::__cxx11::basic_string' is not derived from 'const __gnu_cxx::__normal_iterator<_Iterator, _Container>'
135 | __init = _GLIBCXX_MOVE_IF_20(__init) + *__first;
I want to know how to fix my codes? Thanks.
That's because you do not use std::accumulate properly. Namely, you 1) did not specify the initial value and 2) provided unary predicate instead of a binary. Please check the docs.
The proper way to write what you want would be:
#include <iostream>
#include <numeric>
#include <string>
#include <vector>
using namespace std;
int main() {
vector<string> v = {"abc", "def", "ghi"};
size_t totalSize = accumulate(v.begin(), v.end(), 0,
[](size_t sum, const std::string& str){ return sum + str.size(); });
cout << totalSize << endl;
return 0;
}
Both issues are fixed in this code:
0 is specified as initial value, because std::accumulate needs to know where to start, and
The lambda now accepts two parameters: accumulated value, and the next element.
Also note how std::string is passed by const ref into the lambda, while you passed it by value, which was leading to string copy on each invocation, which is not cool

Listing the Files in a Directory in Visual C++

I have tried to "simplify" a nice piece of example code, the hyperlink to the code is at the end of this message, to specify the directory string instead of passing it as a command line argument. The simplified code compiles and executes, but the filename and size are not what I expect: the file name appears to be a hex number, and the nFileSize.High is larger than the nFileSize.Low (the actual file sizes range from 0 to 100Mb). I think my type casting may have introduced errors. Any suggestions?
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>
#include <cctype>
#include <bitset>
#include <sstream>
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <strsafe.h>
#pragma comment(lib, "User32.lib")
using namespace std;
using namespace System; //set common language runtime support to /clr
int main()
{
WIN32_FIND_DATA ffd;
LARGE_INTEGER filesize;
//TCHAR szDir[MAX_PATH];
//size_t length_of_arg;
HANDLE hFind = INVALID_HANDLE_VALUE;
//DWORD dwError=0;
finstr = "C:\\Users\\MyName\\Documents\\Visual Studio 2010\\Projects\\Data Analysis\\Data Folder\\*";
//Just evaluate the first file before looping over all files
hFind = FindFirstFile((wchar_t*)(finstr.c_str()), &ffd);
wstring wsfname(ffd.cFileName);
string newtemp(wsfname.begin(), wsfname.end());
cout << "1st fname = " << ffd.cFileName << " newtemp = "<< newtemp << " nFSizeLo = "<< ffd.nFileSizeLow << " nFSizeHi = "<< ffd.nFileSizeHigh << "\n";
FindClose(hFind);
return 0;
}
Link to original example from Microsoft
https://msdn.microsoft.com/en-us/library/windows/desktop/aa365200(d=printer,v=vs.85).aspx

How to get an array of strings without using argv - CS50 pset2

I'm currently doing the CS50 Harvard Course and I'm stuck in problem set 2.
I made this program that takes a name and prints the initials, it takes the name in the command line. How can I use get_string() instead of argv, and argc wich is very unorthodox and sloppy, so I can prompt the user to give me her/his name. Thank you.
#include <cs50.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
int main(int argc, string argv[])
{
//How do I use Get_string() so I don't have to use argv and argc??
//iterate over strings on the vector (words)
for (int i = 0; i < argc; i++)
{
//prints the 0 character of each string, use "toupper" to convert into capital letters
printf("%c", toupper(argv[i][0]));
}
printf("\n");
}
use Array,
let's say for 10 names
string name[10];
for (int i = 0; i < 10; i++)
{
name[i] = get_string("Enter your name: /n");
}

Resources