#include <stdio.h>
#include <iostream>
using namespace std;
int main()
{
char * text = new char;
scanf("%c", text);
scanf("%c", text+1);
return 0;
}
Sorry for this lame question...
I'm trying to read a string one char at a time (because I need to check sth for every char..)
For input "ab" the output is "ab" and a ?random? character...
It doesn't work without the 'scanf("%c", text+1);' either.. I can do this using static field, but this version gives me one extra char in the end.. What am I doing wrong? :'(
You allocate one char giving you the pointer text. You then access text[0] and text[1] which clearly give an out of bounds access. I strongly recommend you don't access memory explicitly and use a std::string instead, e.g.:
std::string text;
for (std::istreambuf_iterator<char> it(std::cin), end; it != end; ++it) {
// do whatever checks you need to do
text.push_back(*it);
}
std::cout << "read '" << text << "'\n";
Related
I am a beginner in c++ and I want to enter a string as character by character into an array , so that I can implement a reverse function .. However unlike C when the enter is hit a '\n' is not insterted in the stream.. how can I stop data from being entered ?
my code is :
#include<iostream>
#include<array>
#define SIZE 100
using namespace std;
char *reverse(char *s)
{
array<char, SIZE>b;
int c=0;
for(int i =(SIZE-1);i>=0;i--){
b[i] = s[c];
c++;
}
return s;
}
int main()
{
cout<<"Please insert a string"<<endl;
char a[SIZE];
int i=0;
do{
cin>>a[i];
i++;
}while(a[i-1]!= '\0');
reverse(a);
return 0;
}
When you read character by character, it really reads characters, and newline is considered a white-space character.
Also the array will never be terminated as a C-style string, that's not how reading characters work. That means your loop condition is wrong.
To begin with I suggest you start using std::string for your strings. You can still read character by character. To continue you need to actually check what characters you read, and end reading once you read a newline.
Lastly, your reverse function does not work. First of all the loop itself is wrong, secondly you return the pointer to the original string, not the "reversed" array.
To help you with the reading it could be done something like
std::string str;
while (true)
{
char ch;
std::cin >> ch;
if (ch == '\n')
{
break; // End loop
}
str += ch; // Append character to string
}
Do note that not much of this is really needed as shown in the answer by Stack Danny. Even my code above could be simplified while still reading one character at a time.
Since you tagged your question as C++ (and not C) why not actually solve it with the modern C++ headers (that do exactly what you want, are tested, save and work really fast (rather than own functions))?
#include <string>
#include <algorithm>
#include <iostream>
int main(){
std::string str;
std::cout << "Enter a string: ";
std::getline(std::cin, str);
std::reverse(str.begin(), str.end());
std::cout << str << std::endl;
return 0;
}
output:
Enter a string: Hello Test 4321
1234 tseT olleH
Can someone explain to me how to properly search for a "tab" character stored in a string class?
For example:
text.txt contents:
std::cout << "Hello"; // contains one tab space
User enters on prompt: ./a.out < text.txt
main.cpp:
string arrey;
getline(cin, arrey);
int i = 0;
while( i != 10){
if(arrey[i] == "\t") // error here
{
std::cout << "I found a tab!!!!"
}
i++;
}
Since there is only one tab space in the textfile, I am assuming it is stored in index [0], but the problem is that I can't seem to make a comparison and I don't know any other way of searching it. Can someone help explain an alternative?
Error: ISO C++ forbids comparison between pointer and integer
First of all, what is i? And secondly, when you use array-indexing of a std::string object, you get a character (i.e. a char) and not a string.
The char is converted to an int and then the compiler tries to compare that int with the pointer to the string literal, and you can't compare plain integers with pointers.
You can however compare a character with another character, like in
arrey[i] == '\t'
std::string::find() might help.
Try this:
...
if(arrey.find('\t') != string::npos)
{
std::cout << "I found a tab!!!!";
}
More info on std::string::find is available here.
Why not using what C++ library provides? You could do it like this:
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
string arrey;
getline(cin, arrey);
if (arrey.find("\t") != std::string::npos) {
std::cout << "found a tab!" << '\n';
}
return 0;
}
The code is based on this answer. Here is the ref for std::find.
About your edit, how are sure that the input is going to be 10 positions? That might be too little or too big! If it is less than the actual size of the input, you won't look all the characters of the string and if it is too big, you are going to overflow!
You could use .size(), which says the size of the string and use a for loop like this:
#include <iostream>
#include <string>
using namespace std;
int main() {
string arrey;
getline(cin, arrey);
for(unsigned int i = 0; i < arrey.size(); ++i) {
if (arrey[i] == '\t') {
std::cout << "I found a tab!!!!";
}
}
return 0;
}
i am trying to create a simple (modularized) c++ program that reads the users input and spits it back out.
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
void _printOut(char * output)
{
cout << output << endl;
}
char * readUserInput()
{
char userInput[256];
cin >> userInput;
return userInput;
}
int _tmain(int argc, _TCHAR* argv[])
{
_printOut("Enter your name: ");
char * userName = readUserInput();
_printOut("Hello");
_printOut(userName);
system("pause");
return 0;
}
Enter your name:
aaaa
Hello
╠╠╠╠╠╠╠╠
Press any key to continue . . .
if i print out the userInput variable in the readUserInput function it prints out what is inputted. However trying to print out the userInput variable store as userName in the _tmain function results in a incomprehensible sequence of chars being printed out. ie. ╠╠╠╠╠╠╠╠.
By my best guess, this could be caused by pointer issues, but as far as I can tell I am referencing everything correctly.
Debugging this code:
at this line: _printOut("Hello"); in method: _tmain [userName = "abcdefg"]
at this line: _printOut(userName); in method _tmain [userName = "†UX"]
so I am wondering how the value of username is changing when it isn't assigned or manipulated between the two lines.
char * readUserInput()
{
char userInput[256];
cin >> userInput;
return userInput;
}
The char userInput[256]; array only exists during the function call. Once you hit the bottom of the function it ceases to exist, and you return a pointer to some garbage memory.
This is called local scope.
And anyway, what if someone has a reaally long name (longer than 255 characters).
Consider using std::string, which will solve both problems.
std::string readUserInput()
{
std::string inp;
std::cin >> inp;
return inp;
}
and
void printOut (const std::string& toPrint)
{
std::cout << toPrint << '\n';
}
(Also, and this is less important, the name _printOut is not allowed in this context, because of the leading _. See here, although it might go over your head if you are a beginner.)
Edit An even better way to go is to use std::getline to read a whole line at a time into a std::string. However, because of the way they treat spaces, and in particular '\n' newline characters, getline(...) and cin>>... don't play nicely together. It's usually just best to pick one and stick with it throughout your program. Here's how readUserInput() would look:
std::string readUserInput()
{
std::string line;
std::getline(std::cin, line);
return line;
}
This way if a user enters a name containing whitespace (e.g. "BoB T. Fish") you will read the whole name, rather than just "BoB" (and then leaving the rest to confuse you the next time you read).
The reason this can be iffy to mix cin>>... with getline is that cin>>... will read as much as it can up to whitespace, then leave the rest behind. So apart from mayb emissing someone's surname, if they enter a name without spaces, it will just leave the last newline character on the input stream. Then when you come along and do getline, you don't get the next line of user input. You get the empty line that has been left behind. If you had instead used cin>> again, the newline would have been ignored.
e.g. Consider this user input:
Hello\n
World\n
If you do the first read with cin>>, you get "Hello" in your program, and left with
\n
World\n
If you then do the second read with getline, you get "" in your program, and left with
World\n
char userInput[256]; will be destroyed when readUserInput exits, so the pointer you return is invalid.
Use std::string instead.
Or allocate the variable dynamically, or pass an automatic variable as parameter.
userInput variable gets destroyed once it goes out of scope.
Local variables get stored on stack. Once the function execution completes, the variables get destroyed.
Either you need to use dynamically allocated char pointer(Stores on Heap) or std::string
you are using a pointer to a buffer (In stack) which is already out of scope.
Try this:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
void _printOut(char * output)
{
cout << output << endl;
}
char * readUserInput()
{
//Allocate in Heap, instead of stack
char* userInput = new char[256];
cin >> userInput;
return userInput;
}
int main(int argc, char* argv[])
{
_printOut("Enter your name: ");
char * userName = readUserInput();
_printOut("Hello");
_printOut(userName);
system("pause");
return 0;
}
A better way would be to use std::string
Your problem here is a scoping issue:
char userInput[256]; defines a local variable that is only valid within its own scope (between ist set of {} brackets).
You essentially return a valid pointer that becomes invalid once you leaves the function, because it's freed.
You're violating a basic rule: never return pointers to local (non-static) variables.
To fix this, make your userInput static or return a new string (create a new string every call using new) or use copyable objects rather than pointers (like std::string).
This is a very strange issue. I'm trying to print a large text file, it's a Wikipedia entry. It happens to be the page on Velocity. So, when I tell it to print the file, it prints "In", when it should print "In physics, velocity is etc, etc etc".
Here's the code I'm using to print out:
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ifstream wiki;
wiki.open("./wiki/velocity.txt");
char* wikiRead;
wiki >> wikiRead;
cout << wikiRead << endl;
wiki.close();
}
Please help.
wiki >> wikiRead;
The default delimiter for stream is space, so when the stream encounters a space, it simply stops reading, that is why it reads only one word.
If you want the stream to read all words, the you've to use a loop as:
char* wikiRead = new char[1024]; //must allocate some memory!
while(wiki >> wikiRead)
{
cout << wikiRead << endl;
}
wiki.close();
delete []wikiRead; //must deallocate the memory
This will print all the words in the file, each on a new line. Note if any of the word in the file is more than 1024 character long, then this program would invoke undefined behavior, and the program might crash. In that case, you've to allocate a bigger chunk of memory.
But why use char* in the first place? In C++, you've better choice: Use std::string.
#include<string>
std::string word;
while(wiki >> word)
{
cout << word << endl;
}
wiki.close();
Its better now.
If you want to read line-by-line, instead of word-by-word, then use std::getline as:
std::string line;
while(std::getline(wiki, line))
{
cout << line << endl;
}
wiki.close();
This will read a complete line, even if the line contains spaces between the words, and will print each line a newline.
You ask the stream to read the (binary) value of a pointer (probably 4 bytes, depending on your machine architecture), then you ask it to print the text pointed to by those 4 bytes!
I wonder why you ignored the compiler warning (most of the modern compiler warns you about using uninitialized variables). How about this?
ifstream wiki;
wiki.open("./wiki/velocity.txt");
char wikiRead[255];
wiki >> wikiRead;
cout << wikiRead << endl;
wiki.close();
Alternatively I'd suggest you to use string object with getline to get a single line of text.
string str;
getline(wiki, str);
The >> operator applied to a char * reads only one word. Moreover, you're reading into an uninitialized pointer, which is not valid. Usually std::string, not char *, is used for string processing in C++.
If you only want to print the file's contents, you can hook the file's buffer directly to std::cout:
int main() {
std::ifstream wiki("./wiki/velocity.txt");
std::cout << wiki.rdbuf() << '\n';
}
If you want to put the contents into an automatically-allocated string, use std::getline with the delimiter disabled.
int main() {
std::ifstream wiki("./wiki/velocity.txt");
std::string wiki_contents;
getline( wiki, wiki_contents, '\0' /* do not stop at newline */ );
std::cout << wiki_contents << '\n'; // do something with the string
}
Since you want to read a large file, reading it block by block is a better way.
ifstream wiki;
wiki.open("./wiki/velocity.txt");
const int buf_size = 1024;
char* wikiRead = 0;
int cnt = 1;
do
{
wikiRead = realloc( wikiRead, bufsize*cnt );
wiki.Read( wikiRead + (bufSize*(cnt-1)), buf_size ); //appends to reallocated memory
cnt++;
}while( !wiki.eof())
wikiRead[(bufSize*(cnt-2)) + wiki.gcount() + 1] = '\0'; // null termination.
wiki.Close();
cout << wikiRead;
delete[] wikiRead;
The operator>> is designed to only read one word at a time. If you want to read lines, use getline.
#include <iostream>
#include <fstream>
#include<string>
using namespace std;
int main()
{
ifstream wiki;
wiki.open("./wiki/velocity.txt");
string wikiRead;
while (getline(wiki, wikiRead))
{
cout << wikiRead << endl;
}
wiki.close();
}
I am trying to convert an integer to char array and I came across this piece of code
int i = 5;
std::string s;
std::stringstream out;
out << i;
s = out.str();
But when I try to print the value of s it still prints 5. I don't know if its supposed to do that or am I doing something wrong? Besides I would prefer if I could convert the same int to char array. But I would appreciate any help in the matter.
Thanks!
Code taken from: Alternative to itoa() for converting integer to string C++?
Yes, it's supposed to do that. You'd (primarily) notice the difference from just printing a number out directly if you do some other string-type manipulation on the result (e.g., concatenating it with other strings, searching for characters in the string).
Just for example:
std::cout << i+i; // should print "10"
std::cout << s+s; // should print "55"
Besides I would prefer if I could convert the same int to char array.
char *charPtr = new char[ s.length() + 1 ] ; // s is the string in the snippet posted
strcpy( charPtr, s.c_str() ) ;
// .......
delete[] charPtr ; // Should do this, else memory leak.
If you would like to stop worrying about issues like that you might be interested in boost/lexical_cast.hpp.
#include <boost/lexical_cast.hpp>
#include <string>
#include <iostream>
int main() {
const int i=5;
const char* s = boost::lexical_cast<std::string>(i).c_str();
std::cout << s << std::endl;
}