C++ reading the first line from a file using .getline() - c++

Im having a hard time understanding how to read the first line of a file. im trying to read the 1st line of a file and then check to see if its blank. this is what i came up with but still not working
void buildTree( NodePtr &root, ifstream& input )
{
char line [50];
line= input.getline();
if ( line == NULL )
{
root = NULL;
return;
}
}

void buildTree( NodePtr &root, ifstream& input )
{
char line [50];
input.getline(line, sizeof line);
if (strlen(line) == 0)
{
root = NULL;
return;
}
}

I think you are doing it wrong the format for getline() is as follows.
If you are using char array :
char buffer[256];
input.getline(buffer, 256);
If you are using string :
string buffer;
getline(input, buffer);

Related

Trying to print out the line numbers of a file, using an int variable

I was working on a cs project in c++, we had to open a file read the words and print them out in alphabetical order and next to the word print what line it was found on. I used recursive functions to do this but for some reason my counter which i was using to mark the line numbers will not update. I tried using a pointer for it but still nothing. I might have done the pointer wrong but i made the int var global so that should have handled it, but still nothing. I already turned in the assignment, but I want to know why the counter never worked. There are a few hacks in this code, like convert string to c_str(), but that was just to try and get my OR arguments to work, please ignore them.
Any advice?
#include<iostream>
#include<algorithm> //This is to do a comparison of ASCII characters.
#include<cctype> //This is to convert capital letters to lowercase.
#include<string> //This is to work with strings
#include<fstream> //This is to work with getline().
#include<cstring>
using namespace std;
// Node
struct node {
int line;
string word;
node* left;
node* right;
};
// MakeNode Function creates nodes
node* makeNode(string word, int line) {
node* newNode = new node();
newNode->word = word;
newNode->left = newNode->right = NULL;
return newNode;
delete newNode;
}
// Function to insert new nodes into the tree.
node* Insert(node* root,string word, int line) {
if(root == NULL) { // empty tree
root = makeNode(word, line);
}
// If word is less then root-word
else if(word <= root->word) {
root->left = Insert(root->left,word, line);
root->line = line;
}
// If word is greater then root-word
else {
root->right = Insert(root->right,word, line);
root->line = line;
}
return root;
}
// Print function to print tree
void printTree(node* root)
{
if (root == NULL){// If tree doesn't exist
return;
}
else{
printTree(root->left);
cout<<root->word<<"\t"<<root->line<<endl;
printTree(root->right);
}
}
int main() {
int lineNum = 1; // Set line equal to one.
// cout<<lineNum<<endl;
node* root = NULL; // Creating an empty tree
string word; // Var to hold word
ifstream quote ("quote.txt"); // Opens the text file
getline(quote,word,' '); // Gets the words from the text file.
root = Insert(root, word, lineNum);
while(!quote.eof() || word != "#"){// While loop to read all words from text file.
int * line = lineNum;
*line++;
cout<<"This is the word right now: "<<word<<endl;
char *newLine = new char[word.length()+1];
strcpy(newLine, word.c_str());
cout<<"This is the newLine[0] value right now: "<<newLine[0]<<endl;
cout<<"This is lineNum after the if"<<*line<<endl;
if(newLine[0] == '\n'){// Increments line by keeping track of \n line char.
cout<<"This is lineNum after the if"<<*line<<endl;
}
unsigned wordSize = word.size();
if(wordSize > 10){// Shortens word if it is longer then ten chars.
word.resize(10);
}
root = Insert(root, word, *line);
quote>>word;
delete[] newLine;
}// End of While
quote.close();
printTree(root);
}
/***********************************************************************
this is the content of the quote file:
civilization of science
science is knowledge
knowledge is our destiny
#// this hash is to mark the end of the paragraph.
/**************************************************************************
This is a scaled down version of what the problem is, as you can see the
*ptr variable is not updating.*/
int main()
{
int num = 1;
int *ptr = &num;
cout<<*ptr<<endl;
int key = 0;
while(key < 5){
cout<<"This is *prt: "<<*ptr<<endl;
cout<<"This is key: "<<key<<endl;
key++;
*ptr++;
}
return 0;
}
While Nathan Oliver is correct in his assessment you probably might also want to take a look at this:
int * line = lineNum;
I'm not sure why you're using a pointer but given the rest of your code I'm not sure A) it is doing what you think it is doing and B) why it isn't crashing. Were I a gambling man I'd wager this is your error right here.

read in txt file in C++

I have a .txt parameter file like this:
#Stage
filename = "a.txt";
...
#Stage
filename = "b.txt";
...
Basically I want to read one stage each time I access the parameter file.
I planed to use getline in C++ with delimiter "#Stage" to do this. Or there is a better way to solve this? Any sample codes will be helpful.
*struct content{
DATA data;
content* next;
};
struct List{
content * head;
};
static List * list;
char buf[100];
FILE * f = fopen(filename);
while(NULL != fgets(buf,f))
{
char str[100] ={0};
sccanf(buf,"%s",str);
if(strcmp("#Stage",str) == 0)
{
// read content and add to list
cnntent * p = new content();
list->add();
}
else
{
//update content in last node
list->last().data =
}
}*
Maybe I should express more clear. Anyway, I manage like this:
ifstream file1;
file1.open(parfile, ios::binary);
if (!file1) {
cout<<"Error opening file"<<parfile<<"for read"<<endl;
exit(1);
}
std::istreambuf_iterator<char> eos;
std::string s(std::istreambuf_iterator<char>(file1), eos);
unsigned int block_begin = 0;
unsigned int block_end = string::npos;
for (unsigned int i=0; i<stage; i++) {
if(s.find("#STAGE", block_begin)!=string::npos) {
block_begin = s.find("#STAGE", block_begin);
}
}
if(s.find("#STAGE", block_begin)!=string::npos) {
block_end = s.find("#STAGE", block_begin);
}
string block = s.substr(block_begin, block_end);
stringstream ss(block);
....
I'd read line by line, ignoring the lines, starting with # (or the lines, with content #Stage, depending on the format/goal) (as there's no getline version, taking std::string as delimiter).

Reading short from file

I'm trying to read a short from a binary file, but I end up with a lot of 0's
This is the write function
void AudioBuffer::WriteToFile(const string& strFilename)
{
fstream fout(strFilename.c_str(), ios::out|ios::binary);
short sample;
for (VECTOR_SHORT_ITER iter = m_vectorSamples.begin(); iter != m_vectorSamples.end(); iter++)
{
sample = (short) *iter;
fout.write((char *) &sample, sizeof(short));
}
fout.close();
}
And this is what I've got for the reading function, I'm aware of the possible overflow with atoi
void AudioBuffer::FileToBuffer(const string& strFilename)
{
fstream fin(strFilename.c_str(), ios::in|ios::binary);
short iSample;
char *temp = new char[sizeof(short)];
cout<<"Samples Output"<<endl;
while(!fin.eof())
{
fin.read(temp,sizeof(short));
iSample = atoi(temp);
cout<<iSample< " ";
m_vectorSamples.push_back(iSample);
*temp = NULL;
}
fin.close();
}
Also, clearing the char pointer by doing the *temp = NULL isn't the best thing right?
Thanks
Since you're just writing raw bits into the file, you want to read the same way, something on this order:
void AudioBuffer::FileToBuffer(const string& strFilename)
{
ifstream fin(strFilename.c_str(), ios::in|ios::binary);
short iSample;
cout<<"Samples Output"<<endl;
while(fin.read((char *)&iSample,sizeof(short)))
{
cout<<iSample<< " ";
m_vectorSamples.push_back(iSample);
}
}

How to read a text char by char and line by line on c++?

its me again with this project. im having a problem reading the text on my input cause the program never ends. The problem its here full description of the problem
but i dont know how to read the text char by char , and then read the next line the same way.
freopen("input.txt","rt",stdin);
freopen("output.txt","wt",stdout);
int n=-1;
int m=-1;
int cont =0;
int VMatriz[100][100]={0};
int Mapa[100][100]={0};
while(n!=0 && m!=0)
{
scanf("%d %d",&n,&m);
if (n==0 && m==0)
break;
cont++;
printf("Field # %d",cont);
for (int i=0;i<n;i++)
{ printf("/n");
for (int j=0;j<m;j++)
{
//scanf("%d ",&Mapa[i][j]);
Mapa[i][j]=getchar();
if (Mapa[i][j]=='*')
{
if (j-1>=0)
VMatriz[i][j-1]++;
if (j+1<m)
VMatriz[i][j+1]++;
if (i-1>=0)
VMatriz[i-1][j]++;
if (i+1<m)
VMatriz[i+1][j]++;
if (j-1>=0 && i-1>0)
VMatriz[i-1][j-1]++;
if (j-1>=0 && i+1<m)
VMatriz[i+1][j-1]++;
if (j+1<m && i-1>0)
VMatriz[i-1][j+1]++;
if (j+1<m && i+1<m)
VMatriz[i+1][j+1]++;
VMatriz[i][j]='*';
printf("%d",VMatriz[i][j]);
}
}
}
printf("/n");
}
return 0;
First make the logic simple
Read Line by line till you reach the EOF
Parse the line for each char
You can use CStdioFile
CStdioFile file (_T("File.txt"), CStdioFile::modeRead);
CString buffer;
while (file.ReadString(buffer))
{
CString strLine = buffer;
//Parse the strLine for each character
}

Line by line reading in C and C++?

I want to read line by line from a file in C or C++, and I know how to do that when I assume some fixed size of a line, but is there a simple way to somehow calculate or get the exact size needed for a line or all lines in file? (Reading word by word until newline is also good for me if anyone can do it that way.)
If you use a streamed reader, all this will be hidden from you. See getline. The example below is based from the code here.
// getline with strings
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main () {
string str;
ifstream ifs("data.txt");
getline (ifs,str);
cout << "first line of the file is " << str << ".\n";
}
In C, if you have POSIX 2008 libraries (more recent versions of Linux, for example), you can use the POSIX getline() function. If you don't have the function in your libraries, you can implement it easily enough, which is probably better than inventing your own interface to do the job.
In C++, you can use std::getline().
Even though the two functions have the same basic name, the calling conventions and semantics are quite different (because the languages C and C++ are quite different) - except that they both read a line of data from a file stream, of course.
There isn't an easy way to tell how big the longest line in a file is - except by reading the whole file to find out, which is kind of wasteful.
I would use an IFStream and use getline to read from a file.
http://www.cplusplus.com/doc/tutorial/files/
int main () {
string line;
ifstream myfile ("example.txt");
if (myfile.is_open())
{
while ( myfile.good() )
{
getline (myfile,line);
cout << line << endl;
}
myfile.close();
}
else cout << "Unable to open file";
return 0;
}
You can't get the length of line until after you read it in. You can, however, read into a buffer repeatedly until you reach the end of line.
For programming in c, try using fgets to read in a line of code. It will read n characters or stop if it encounters a newline. You can read in a small buffer of size n until the last character in the string is the newline.
See the link above for more information.
Here is an example on how to read an display a full line of file using a small buffer:
#include <stdio.h>
#include <string.h>
int main()
{
FILE * pFile;
const int n = 5;
char mystring [n];
int lineLength = 0;
pFile = fopen ("myfile.txt" , "r");
if (pFile == NULL)
{
perror ("Error opening file");
}
else
{
do
{
fgets (mystring , n , pFile);
puts (mystring);
lineLength += strlen(mystring);
} while(mystring[strlen ( mystring)-1] != '\n' && !feof(pFile));
fclose (pFile);
}
printf("Line Length: %d\n", lineLength);
return 0;
}
In C++ you can use the std::getline function, which takes a stream and reads up to the first '\n' character. In C, I would just use fgets and keep reallocating a buffer until the last character is the '\n', then we know we have read the entire line.
C++:
std::ifstream file("myfile.txt");
std::string line;
std::getline(file, line);
std::cout << line;
C:
// I didn't test this code I just made it off the top of my head.
FILE* file = fopen("myfile.txt", "r");
size_t cap = 256;
size_t len = 0;
char* line = malloc(cap);
for (;;) {
fgets(&line[len], cap - len, file);
len = strlen(line);
if (line[len-1] != '\n' && !feof(file)) {
cap <<= 1;
line = realloc(line, cap);
} else {
break;
}
}
printf("%s", line);
getline is only POSIX, here is an ANSI (NO max-line-size info needed!):
const char* getline(FILE *f,char **r)
{
char t[100];
if( feof(f) )
return 0;
**r=0;
while( fgets(t,100,f) )
{
char *p=strchr(t,'\n');
if( p )
{
*p=0;
if( (p=strchr(t,'\r')) ) *p=0;
*r=realloc(*r,strlen(*r)+1+strlen(t));
strcat(*r,t);
return *r;
}
else
{
if( (p=strchr(t,'\r')) ) *p=0;
*r=realloc(*r,strlen(*r)+1+strlen(t));
strcat(*r,t);
}
}
return feof(f)?(**r?*r:0):*r;
}
and now it's easy and short in your main:
char *line,*buffer = malloc(100);
FILE *f=fopen("yourfile.txt","rb");
if( !f ) return;
setvbuf(f,0,_IOLBF,4096);
while( (line=getline(f,&buffer)) )
puts(line);
fclose(f);
free(buffer);
it works on windows for Windows AND Unix-textfiles,
it works on Unix for Unix AND Windows-textfiles
Here is a C++ way of reading the lines, using std algorithms and iterators:
#include <iostream>
#include <iterator>
#include <vector>
#include <algorithm>
struct getline :
public std::iterator<std::input_iterator_tag, std::string>
{
std::istream* in;
std::string line;
getline(std::istream& in) : in(&in) {
++*this;
}
getline() : in(0) {
}
getline& operator++() {
if(in && !std::getline(*in, line)) in = 0;
}
std::string operator*() const {
return line;
}
bool operator!=(const getline& rhs) const {
return !in != !rhs.in;
}
};
int main() {
std::vector<std::string> v;
std::copy(getline(std::cin), getline(), std::back_inserter(v));
}