I'm trying to read the data from a file using pointers but it gives error at the getline part that goes by "no instance of overloaded function". Couldn't figure out how to go about this..
Code is below:
#include<iostream>
#include<fstream>
using namespace std;
void read(const char * const, char const *);
int main()
{
char filename[20] = { "sentence.txt" }, data[50] = { '\0' };
read(filename, data);
return 0;
}
void read(const char * const ptr, char const * ptr2)
{
ifstream file;
file.open(ptr);
if (!file.is_open())
{
cout << "File not found " << endl;
exit(0);
}
else
{
while (!file.eof())
{
file.getline(ptr2, 49, ' ');
cout << ptr2 << endl;
}
file.close();
}
}
Function read is already defined in the C++ libraries:
https://en.cppreference.com/mwiki/index.php?title=Special%3ASearch&search=read
You should use a different name for your function.
Also as written in the comments, const char * and char const * are the same. They are pointers to constant char, which doesn't let you modify the contents of the char array. What you probably wanted is constant pointer to char:
char * const
Ok it was just a simple error that I can't believe I didn't see. The asterisk should be before const so correct indentation would be char * const ptr2 and not char const * ptr2
Call me dumb duh.
Related
How do I create a dynamic array of fixed length strings?
I created class AString which has pointers to struct _str which has fixed-length array data.
How to assign values, and what is wrong?
#include "stdafx.h"
#include <iostream>
struct _str {
char data[20];
};
class AString {
public:
AString();
~AString();
void Add(_str string);
private:
_str *str;
int count;
};
AString::AString() {
std::cout << "Constructor" << std::endl;
str = nullptr;
count = 0;
}
AString::~AString() {
std::cout << "Destructor" << std::endl;
if (str != nullptr) delete[] str;
}
void AString::Add(_str string) {
_str *str2 = new _str[count+1];
for (int i=0;i<count;i++) {
str2[i] = str[i];
}
delete[] str;
str = str2;
count++;
str[count-1] = string;
}
int _tmain(int argc, _TCHAR* argv[])
{
AString astring;
_str str1;
str1.data="0123456789012345678"; // cannot convert from 'const char[20]' to 'char[20]'
astring.Add(str1);
std::cin.get();
return 0;
}
str1.data="0123456789012345678";: cannot convert from 'const char[20]' to 'char[20]'
Want to:
not use _str str1;, and use char str1[20];
As for me, I used this:
strcpy(str1.data, "0123456789012345678");
Here is the main:
int main(int argc, char* argv[])
{
AString astring;
_str str1;
//str1.data=const_cast<char>("0123456789012345678"); // cannot convert from 'const char[20]' to 'char[20]'
strcpy(str1.data, "0123456789012345678");
astring.Add(str1);
std::cout << str1.data;
std::cin.get();
return 0;
}
The result is as follows:
Constructor
0123456789012345678
First of all, I would recomend you yo use std::string or std::array. But if you forced to use char[], I would recomend you to use strncpy instead of operator =, so it would looks like this
strncpy(str1.data,"0123456789012345678", 20); // cannot convert from 'const char[20]' to 'char[20]'
To copy char* or block of memory, it is better to use memcpy!
void* memcpy (void* destination, const void* source, size_t length);
It copies the values of length bytes starting the location pointed to by source directly to the memory block pointed to by destination. Note that, the underlying type of the objects pointed to by both the source and destination pointers dose not matter.
You can also use strncpy.
char* strncpy(char* destination, const char* source, size_t length);
It works properly for your code but if there is/are some 0 valued bytes, the strncpy consider it as null-termination and coping continued with '0' i.e. (pad) until length is satisfied.
try
memcpy(str1.data, "0123456789012345678", 20);
You can't assign to arrays - that's just the way it is.
You could use strncpy in main, or get an assignable array with std::array<char, 20>, but if there was a need to do this by hand, I would add constructors (and hide the implementation details) in order to keep things safe:
class _str {
public:
typedef char base[20];
_str() { data[0] = 0; }
_str(const base& in) { strncpy(data, in, 20); }
const base& get() const { return data; }
private:
base data;
};
and then you can
AString astring;
_str str1 = "01234567890123456789"; // Fine
astring.Add(str1);
std::cout << str1.get();
_str str2 = "012345678901234567890"; // Compilation error
_str str3 = "0"; // Compilation error
I'm trying to declare a char* using dynamic memory allocation then initialize it with a string of characters, but I keep getting this error...
Error Message:
a value of type "const char *" cannot be used to initialize an entity of type "int *"
Code:
void main() {
char *alphabet = new char();
alphabet = "abcdefghijklmnopqrstuvwxyz";
cout << alphabet;
system("pause");
}
I understand that this
void main() {
char *alphabet = new char();
cin.getline(alphabet, 255);
cout << alphabet;
system("pause");
}
will work, but I don't understand why I can't initialize it without user input;
Your question is not good. But I still give use a question. you can try as below:
#include<iostream>
using namespace std;
void showAlphabetArray(char*alp)
{
for(int i=0;i<26;i++)
{
cout<<alp[i];
}
}
int main() {
//declare and init `char` array
char *alphabet = new char[26];
//init value
for(int i=0;i<26;i++)
{
alphabet[i] = i + 97;
}
showAlphabetArray(alphabet);
system("pause");
}
You should reference to ASCII https://en.wikipedia.org/wiki/ASCII
I have an assignment of saving some objects data in a specific order of its data members, I'll try to simplfy . Consider this Base class constructor from a binary file. (Please note that it was not my choice to use char *) .
Base(ifstream & in_file) {
int n;
in_file.read((char *)&n, sizeof(n));
m_var = new char[n + 1];
in_file.read(m_var, n);
m_var[n] = '\0';
in_file.read((char *)&m_intvar, sizeof(m_intvar));
}
It has to initialize m_var (char *) and another integer variable. This code works, though it requiers to save the length of the char * for me to allocate the memory.
The problem starts here. I was instructed not to save the size of the string, but to only enter a \n after each value i write to the file. So I need some how to read the file, and get the string until the \n character.
I was thinking about reading char by char, but couldn't find a way to do it, I assume there is an istream function that offers that. Some similar function to >> of a text file would also be good I assume.
After consulting cppreference.com I end up as follows:
#include <fstream>
#include <iostream>
#include <cstring>
class Base
{
public:
Base(std::istream & in_file) { // NOTE: changed to istream to allow reading from any stream not just files
in_file.read((char *)&n, sizeof(n));
char buffer[1024];
in_file.get(buffer, sizeof(buffer), '\n');
size_t gcount = in_file.gcount();
if (in_file.get() != '\n')
{
throw std::runtime_error("binary string to long"); // you may want to implement a loop here using peek() to check for newline
}
m_var = new char[gcount];
std::copy(buffer, buffer + gcount, m_var);
}
Base(int num, const char* strg)
: n(num)
, m_var(strdup(strg))
{
}
bool operator == (const Base& rhs)
{
return n == rhs.n && strcpy(m_var, rhs.m_var);
}
void write(std::ostream& out)
{
out.write((char*)&n, sizeof(n));
out.write(m_var, strlen(m_var));
out.write("\n", 1);
}
int n;
char* m_var = nullptr;
~Base()
{
delete m_var;
}
};
int main(int, char**)
{
Base b1(10, "Hello Word!");
{
std::ofstream out("testfile.bin");
b1.write(out);
}
std::ifstream in("testfile.bin");
Base b2(in);
if (b1 == b2)
{
std::cout << "read ok!" << std::endl;
}
else
{
std::cout << "read failed!" << std::endl;
}
return 0;
}
4 years later but I was having a similar problem and found this post.
You can read char by char as you mention, with a loop.
int i;
for(i=0;;i++){
cout<<i;
in_file.read(&buffer[i],sizeof(char));
if buffer[i]=='\n') break;
}
The only problem with the code I came up is it saves the '\n'. But you can and should replace it to the NULL char '\0' after having found the new line '\n'.
(buffer[i]=='\0')
Please correct me if I am mistaken.
I am trying to understand pointers a little better and have a hard time to figure out why my code causes a debug assertion failure.
When i comment out "while (*neu++ = *s++);" and comment in "strcopy(neu, s);" it works just fine. Shouldn't they do the same?
#include <iostream>
#include <cstring>
using namespace std;
void strcopy(char* ziel, const char* quelle)
{
while (*ziel++ = *quelle++);
}
char* strdupl(const char* s)
{
char *neu = new char[strlen(s) + 1];
while (*neu++ = *s++);
//strcopy(neu, s);
return neu;
}
int main()
{
const char *const original = "have fun";
cout << original << endl;
char *cpy = strdupl(original);
cout << cpy << endl;
delete[] cpy;
return 0;
}
strcopy takes a copy of the pointer neu, so neu still points to the beginning of the string when you return it. With the while loop inside of strdup1 you are modifying neu before you return it. Calling delete on this pointer causes the failure because it's different from what was new'd.
The solution is to use a temporary variable to increment and copy over the string.
char *neu = ...
char *tmp = neu;
while (*tmp++ = *s++);
return neu;
Ok so this code does compile, and it does run, but it does NOT give me the correct output for EITHER the original or reverse array, just gibberish. I spent the last 4 hours trying to see where I went wrong (it wasn't working at all before and now that I got it to at least output what SHOULD be a C-string, i get gibberish). Someone please help me see where I went wrong.
#include <iostream>
#include <cstring>
using namespace std;
char* getInput();
char* getReverse(char[], int);
void displayResults(char *, char *);
const int MAX_SIZE = 21;
int main()
{
//program to create a c-string and then output the reverse order
char *original;
char *reverse;
original = getInput();
int originalSize = strlen(original);
reverse = getReverse(original, originalSize);
displayResults(original, reverse);
return 0;
}
/***************************************************
Definition of function- getInput: *
prompts the user to enter in a line of text to a *
max amount of characters. Returns a pointer to the *
C-string array. *
****************************************************/
char* getInput()
{
char *originalptr;
char original[MAX_SIZE];
cout << "Enter a word or line of text up to a max of 20 characters\nand will have it output in reverse!" << endl;
cin.getline(original, MAX_SIZE);
originalptr = original;
return originalptr;
}
char* getReverse(char *reverseThis, int size)
{
char* reverseOutput;
char reverse[MAX_SIZE];
int counter = 0;
while(*reverseThis != '\0')
{
reverse[counter] = *(reverseThis + (size - counter));
reverseThis++;
counter++;
}
reverseOutput = reverse;
return reverseOutput;
}
void displayResults(char *original, char *reverse)
{
cout << "\nYou originally entered: " << original << endl;
cout << "In reverse order: " << reverse << endl;
}
In 'getReverse' you are allocating the variable 'reverse' on the STACK meaning the data will be GONE WHEN THE FUNCTION RETURNS, no matter how many pointers reference that data.
I would declare 'reverse' in main with 'char reverse[MAX_SIZE];', then have the function take a parameter 'char reverse[]', which the function would then modify.
You are returning a pointer to a local array. The array original is destroyed after the function getInput exits. So original in main is pointing at something which no longer exists, garbage in other words. getReverse has exactly the same problem.
One way to solve this is to declare the arrays in main, and pass pointers to those arrays to the getInput and getReverse functions, for instance.
int main()
{
//program to create a c-string and then output the reverse order
char original[MAX_SIZE];
char reverse[MAX_SIZE];
getInput(original);
int originalSize = strlen(original);
getReverse(original, originalSize, reverse);
displayResults(original, reverse);
return 0;
}
void getInput(char* original)
{
cout << "Enter a word or line of text up to a max of 20 characters\nand will have it output in reverse!" << endl;
cin.getline(original, MAX_SIZE);
}
// etc
You are wasting too much char* s and data. Why not try this :
(I have not tested the code, but it must work ,probably with minor fixes,if any.)
#define MAXSIZE 20
void getinput(char *in)
{
cin.getline(in,MAXSIZE);
return;
}
void reverse(char *in);
{
int len=strlen(in);
char *store=in;
while(int i=0;i<len/2;i++)
{
char temp;
temp=*in;
*in=*(store+len);
in++;len--;
}
return;
}
int main()
{
char data[MAXSIZE];
getinput(data);
cout<<"Original :"<<data;
reverse(data);
cout<<"reverse"<<data;
}