using namespace std;
char *fx[65537];
void main()
{
FILE *fp;
int i = 0;
int c = 0;
char *token = NULL;
char str1[] = " ";
fp = fopen("fx.txt", "r");
char s[51];
for (c = 0; i <= 65536; c++)
{
token = strtok(fx[c], str1);
while (token != NULL)
{
printf("token : %s", token);
putchar('\n');
token = strtok(NULL, str1);
}
}
while (!feof(fp))
{
i = i++;
fgets(s, 50, fp);
fx[i] = s; //fx 포인터에 s의 임시배열 저장
}
fclose(fp);
}
Hello
I want make a program that read the *.txt file with one line and save char pointer
and I token this char and save
For example
there txt
test.txt
123 654 8765 4213
321 565 4687 8765
652 126 6874 3215
then,
char *a[3] = {123 654 8765 4213, 321 565 4687 8765, 652 126 6874 3215};
char b[3][4];
char b[0][] = {123, 654, 8765, 4213};
char b[1][] = {321, 565, 4687, 8765};
char b[2][] = {652, 126, 6874, 3215};
But I don't know how to that :(
Can you help me?
use vector and string
#include <iostream>
#include <fstream>
#include <vector>
#include <iterator>
#include <string>
int main() {
std::ifstream input("fx.txt");
std::vector<std::string> v((std::istream_iterator<std::string>(input)),std::istream_iterator<std::string>());
for ( std::vector<std::string>::const_iterator iter = v.begin();iter != v.end(); ++iter ) {
std::cout << *iter << std::endl;//print by iterator
}
for(int i=0;i<v.size();++i)
std::cout << v[i] << std::endl;//print by []
}
By C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *fx[65537];
int main(){
FILE *fp;
int i = 0, j;
int c = 0;
char *token = NULL;
char str1[] = " \n";
char s[51];
fp = fopen("fx.txt", "r");
while (fgets(s, sizeof(s), fp)){
token = strtok(s, str1);
while (token != NULL) {
fx[i++] = strdup(token);
if(i == 65537)
break;
token = strtok(NULL, str1);
}
}
fclose(fp);
c = i;
for(i=0;i<c;++i)
printf("%s ", fx[i]);
printf("\n\n");
char *(*b)[4] = (char *(*)[4])fx;
for(i=0;i<3;++i){
for(j=0;j<4;++j)
printf("%s ", b[i][j]);
printf("\n");
}
//deallocation
for(i=0;i<c;++i)
free(fx[i]);
return 0;
}
If there are no restrictions, use strings, get boost and then you can use
vector<string>splitString;
boost::split(splitString,a[i],boost::is_any_of(" "));
this way each element in your string vector (splitString) will contain one "number" of the ith line.
Related
I have coded a program that uses mmap as input to fill a integer 2D vector from a .txt file. The code is part of a larger program and will be submitted to a competition. Is there a way to improve the speed using mmap, or by using a different way all together? Here is the code:
#include <fstream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <iostream>
// for mmap:
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
using namespace std;
const char* map_file(const char* fname, size_t& length);
int main()
{
auto start = std::chrono::high_resolution_clock::now();
size_t length;
auto f = map_file("erasmus.in", length);
auto l = f + length;
int i = 0;
bool flag = false;
string lines;
vector<vector<int> > students(10000); //The number of lines is predefined
const char* temp;
while (f && f!=l) {
string element = "";
temp = static_cast<const char*>(memchr(f, '\n', l-f));
for(f = f; f<=temp; f++)
{
if(!isspace(*f))
{
element += *f;
flag = true;
}
if(isspace(*f) && flag == true)
{
flag = false;
int assigned_element = stoi(element);
students[i].push_back(assigned_element);
element = "";
}
}
i++;
temp++;
}
auto finish = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> elapsed1 = finish - start;
FILE* output = fopen("erasmus.out", "w");
for (int i = 0; i < students.size(); i++)
{
for (int j = 0; j < students[i].size(); j++)
{
fprintf(output, "%d ", students[i][j]);
}
fprintf(output, "\n");
}
std::cout << "Elapsed time: " << elapsed1.count() << " s\n";
return 0;
}
void handle_error(const char* msg) {
perror(msg);
exit(255);
}
const char* map_file(const char* directory, size_t& length)
{
int fileDirectory = open(directory, O_RDONLY);
if (fileDirectory == -1)
handle_error("open");
// obtain file size
struct stat sb;
if (fstat(fileDirectory, &sb) == -1)
handle_error("fstat");
length = sb.st_size;
const char* map = static_cast<const char*>(mmap(NULL, length, PROT_READ, MAP_PRIVATE, fileDirectory, 0u));
if (map == MAP_FAILED)
handle_error("mmap");
return map;
}
The file will be executed on a linux system, if this helps to find the optimal answer. At the end of each line of the .txt
there is a space character (' ') and a newline('\n')
#include <iostream>
#include <fstream>
#include <string.h>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <semaphore.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <sys/ipc.h>
#include <vector>
#include <sstream>
#define SHMSIZE 1024
using namespace std;
namespace patch
{
template < typename T > std::string to_string( const T& n )
{
std::ostringstream stm ;
stm << n ;
return stm.str() ;
}
}
struct process
{
int r;
string name;
vector<string> lines;
};
int main(int argc, char * argv[])
{
int firstRun = 1; //Skipping First Line of Assign-1.ip.
int quantum = 0; //For taking input of quantum.
int count = 0; //For number of processes.
int pchtoint;
string c;
char * pch; //For tokenization.
string reading_file; //Reading a line from file.
char * readarr; //Converting "reading_file" to readarr for tokenization.
process * p;
//=== Quantum Input ===//
cout<<"Enter Quantum size [1-1000]: ";
cin>>quantum;
while(quantum < 1 || quantum > 1000)
{
cout<<"Wrong input!!! Enter Again [1-1000]: ";
cin>>quantum;
}
//=====================//
//===Filing===//
ifstream read("Assign-2.ip");
if(read.is_open())
{
while(!read.eof())
{
getline(read, reading_file);
readarr = new char[reading_file.size() + 1];
for(int i = 0; i < reading_file.length(); i++)
{
readarr[i] = reading_file[i];
}
if(firstRun > 1)
{
int countingline = 0; //counting the number of lines in a process.
pch = strtok (readarr," ,");
while (pch != NULL)
{
c = pch[1];
pchtoint = atoi(c.c_str());
p[pchtoint-1].r++;
p[pchtoint-1].lines.push_back(pch);
for(int i = 0; i < p[pchtoint-1].lines.size(); i++)
cout<<p[pchtoint-1].name<<"=="<<p[pchtoint-1].lines.at(i)<<endl;
pch = strtok (NULL, " ,");
}
}
else
{
pch = strtok (readarr,",.-");
while (pch != NULL)
{
count++;
pch = strtok (NULL, ",.-");
}
p = new process[count];
string s = "p";
for(int i = 0; i < count; i++)
{
s = s + patch::to_string(i+1);
p[i].name = s;
s = s[0];
}
firstRun++;
}
}
}
else
{
cout<<"Cannot open file!!!"<<endl;
}
read.close();
return 0;
}
Enter Quantum size [1-1000]: 2
p1==p1-l1
p2==p2-l1
p3==p3-l1
p1==p1-l1
p1==p1-l2
p2==p2-l1
p2==p2-l2
p3==p3-l1
p3==p3-l2
p1==p1-l1
p1==p1-l2
p1==p1-l3
p3==p3-l1
p3==p3-l2
p3==p3-l3
p1==p1-l1
p1==p1-l2
p1==p1-l3
p1==p1-l4
Segmentation fault (core dumped)
I am reading data from a cvs file. and storing it in struct that is p here. but I don't know why it is giving segmentation fault. I am compiling it on ubuntu terminal.
The input file contains data:
P1, P2, P3,
p1-l1, p2-l1, p3-l1
p1-l2, p2-l2, p3-l2
p1-l3, , p3-l3
p1-l4, ,
my goal is to read in a data file consisting of just one number per line and write the data into a histogram. There are some comments in the file behind # characters. I want to skip these lines.
I have started writing:
TH1F *hist = new TH1F("hist","",4096, -0.5,4095.5);
//TF1 *fitfunc;
char filename[100];
double val;
int i;
char line[256];
sprintf(filename,"test.dat");
FILE* pfile = fopen(filename, "r");
for (i=0;i<=14;i++) {
fgets(line,256,pfile);
cout<<line<<endl;
fscanf(pfile, "%lf /n", &val);
hist->SetBinContent(i,val);
}
But only every other line gets written as "line" while the others are fscanfed.
Would be very nice, if someone could give me a hint.
...so this will obviously not work properly:
TH1F *hist = new TH1F("hist","",4096, -0.5,4095.5);
//TF1 *fitfunc;
char filename[100];
double val;
int i;
char zeile[256];
sprintf(filename,"test.dat");
FILE* pfile = fopen(filename, "r");
for (i=0;i<=14;i++)
{
fgets(zeile,256,pfile);
cout<<"fgets: "<<zeile<<endl;
if (zeile[0]!='#')
{
fscanf(pfile, "%lf /n", &val);
cout<<"val: "<<val<<endl;
hist->SetBinContent(i,val);
}
}
You need to use sscanf() instead of fscanf() after you've read the line with fgets():
TH1F *hist = new TH1F("hist", "", 4096, -0.5, 4095.5);
char filename[100];
char zeile[256];
sprintf(filename, "test.dat");
FILE *pfile = fopen(filename, "r");
if (pfile == 0)
…handle error; do not continue…
for (int i = 0; i < 14 && fgets(zeile, sizeof(zeile), pfile) != 0; i++)
{
cout << "fgets: " << zeile << endl;
if (zeile[0] != '#')
{
double val;
if (sscanf(zeile, "%lf", &val) == 1)
{
cout << "val: " << val << endl;
hist->SetBinContent(i, val);
}
// else … optionally report that line was erroneous
}
}
I left the sprintf() for the file name in place, but it provides marginal value. I'd be tempted to use const char *filename = "test.dat"; so that the error message can report the file name that failed to open without repeating the string literal.
Converted into a standalone test program:
#include <cstdlib>
#include <iostream>
using namespace std;
int main()
{
char filename[100];
char zeile[256];
sprintf(filename, "test.dat");
FILE *pfile = fopen(filename, "r");
if (pfile != 0)
{
for (int i = 0; i < 14 && fgets(zeile, sizeof(zeile), pfile) != 0; i++)
{
cout << "fgets: " << zeile;
if (zeile[0] != '#')
{
double val;
if (sscanf(zeile, "%lf", &val) == 1)
cout << "val: " << val << endl;
}
}
fclose(pfile);
}
return 0;
}
and given a test data file test.dat containing:
1.234
2.345
#3.456
#4.567
5.678
the output from the program shown is:
fgets: 1.234
val: 1.234
fgets: 2.345
val: 2.345
fgets: #3.456
fgets: #4.567
fgets: 5.678
val: 5.678
This generates the three expected val lines and reads but ignores the two comment lines.
I am getting a compile error when I try to access my function
The program retrieves data from 2 different source and is supposed to come together in that one function.
k.cpp: In function 'int main()':
k.cpp:65:10: error: too few arguments to function 'std::vector<std::basic_string<char> > buymngr(FILE*)'
k.cpp:45:26: note: declared here
It is indicating that I am missing a parameter here -> std::vector buymngr(FILE *buyfp)
I am just very unsure of what it is asking for.
#include <cstdio>
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <unistd.h>
#include <cstring>
#include <cstdlib>
#include <vector>
using namespace std;
FILE *init( const char *fname ){
FILE *buyfp = popen( fname, "r" );
return buyfp;
}
vector<string> getmyData()
{
FILE *fp = popen("php orders.php 155", "r");
if (fp == NULL) perror ("Error opening file");
char buff[BUFSIZ];
vector<string> vrecords;
while(fgets(buff, sizeof(buff), fp) != NULL){
size_t n = strlen(buff);
if (n && buff[n - 1] == '\n') buff[n - 1] = '\0';
if (buff[0] != '\0') vrecords.push_back(buff);
}
return vrecords;
}
std::vector<std::string> getmarketbuyData(FILE *buyfp){
char buff2[BUFSIZ];
vector<std::string> vrecs;
while(std::fgets(buff2, sizeof buff2, buyfp) != NULL){
size_t n = std::strlen( buff2 );
if ( n && buff2[n-1] == '\n' ) buff2[n-1] = '\0';
if ( buff2[0] != '\0' ) vrecs.push_back( buff2 );
}
for(int t = 0; t < vrecs.size(); ++t){
cout << vrecs[t] << " " << endl;
}
return vrecs;
}
std::vector<std::string> buymngr(FILE *buyfp){
vector<std::string> buydat;
vector<std::string> markdat;
buyfp = init("php buyorders.php 155");
if (buyfp == NULL) perror ("Error opening file");
if ( buyfp ){
buydat = getmarketbuyData( buyfp );
}
for(int b = 0; b < sizeof(buydat); ++b){
cout << buydat[b] << " " << endl;
}
markdat = getmyData();
for(int l = 0; l < sizeof(markdat); ++l){
cout << markdat[l] << " " << endl;
}
}
//Le Main
int main(void)
{
buymngr(FILE*);
}
How do I get rid of the error? What parameter is it asking for?
Your definition goes like:-
std::vector<std::string> buymngr(FILE *buyfp)
so it's expecting FILE* type as its argument whereas you're calling it:-
buymngr();
without any arguments.
i'm trying to create a map of word==>drow, like polindrom...
the problem is at the final level at "strtok"...
first i split it, then in subsequent call when doing strtok(NULL," "); it works ok.
the problem is when i add the second string "poly_buffer"... seems it works on it....
#include "stdafx.h"
#include <iostream>
#include <cstdio>
#include <string>
#include <map>
#include <string>
using namespace std;
void poly(char *buffer)
{
char temp;
for (int i=0; i<=strlen(buffer); i++)
{
int word_start = i, word_stop = i;
while (buffer[i] != 32 && buffer[i] != '\0') { i++; word_stop++; }
word_stop--;
//swap chars until the middle of word
while (word_stop >= word_start)
{
//swap the chars
temp = buffer[word_stop];
buffer[word_stop] = buffer[word_start];
buffer[word_start] = temp;
word_stop--;
word_start++;
}
word_start = i;
}
}
void main()
{
FILE *fp;
char *buffer;
char *poly_buffer;
long file_size;
map<string,string> map_poly;
fp = fopen("input.txt", "r");
if (fp == NULL) { fputs("File Error",stderr); exit(1); }
//get file size
fseek(fp,1,SEEK_END);
file_size = ftell(fp);
rewind(fp);
//allocate memory
buffer = new char[file_size+1];
poly_buffer = new char[file_size+1];
//get file content into buffer
fread(buffer,1, file_size,fp);
strcpy(poly_buffer,buffer);
buffer[file_size] = '\0';
poly_buffer[file_size] = '\0';
poly(buffer);
buffer = strtok(buffer," ");
poly_buffer = strtok(poly_buffer," ");
while (buffer != NULL)
{
map_poly[buffer] = poly_buffer;
printf("%s ==> %s\n", buffer, poly_buffer);
buffer = strtok(NULL," ");
poly_buffer = strtok(NULL," ");
}
fclose(fp);
while(1);
}
what am i doing wrong ?
the both strtok calls
buffer = strtok(buffer, " ");
poly_buffer = strtok(poly_buffer," ");
are interfering with each other, you need to process them one by one - you cannot do them at the same time because they are sharing static memory in the runtime library. i.e. first do strtok(buffer," ") strtok(NULL, " ") until end, then do strtok( poly_buffer, " ")///
see runtime reference doc for strtok
If you are using C++, why on Earth would you use strtok? Use a stringstream to tokenise and a vector to contain the words:
#include <string>
#include <sstream>
#include <iostream>
#include <vector>
using namespace std;
int main() {
istringsream is( "here are some words" );
string word;
vector <string> words;
while( is >> word ) {
words.push_back( word );
}
for ( unsigned int i = 0; i < words.size(); i++ ) {
cout << "word #" << i << " is " << words[i] << endl;
}
}
From the man page for strtok, strtok_r:
"Avoid using these functions."