I have tried a lot to debug my code but it is still not working.The whole code just crashes but there is no allover error I am presenting the code please try to debug that one.
Code:
#include <iostream>
#include<conio.h>
#include<string.h>
#include<fstream>
using namespace std;
void write(char fname[],char text[])
{
strcat(fname,".txt");
ofstream w(fname,ios::app);
w<<text;
w<<"\n";
w.flush();
w.close();
cout<<" sippy "<<fname<<" ";
}
int main ()
{
int login=0;
char t[100],id[100]="Its id ",pass[100]="Its password";
login=1;
strcpy(t,id);
strcat(t,"\n");
strcat(t,pass);
cout<<" finally ";
write("database",t);
getch();
strcpy(t,id);
getch();
cout<<t<<" showing t here";
getch();
cout<<" hope this works for now ";
getch();
cout<<"\nEnter the text"<<endl;
write(id,t);
}
The above mentioned code does not work on tdm gcc code blocks
Edit 1:
Ok so now the major problem has been detected it is a minor bug usually caused because of drawback of a bad programming style. As it is often suggested that if a string is passed to a function then that particular function allocates a new string at the memory of the passed string. Since the passed string is a literal the code editing the newly formed string would try to edit a read only literal memory which is an error
Literals are read only because if compiler finds the use of same literal at some different place then it would be able to use same memory to flash the contents of literal therefore it becomes a necessity to make a literal read only and use of c-style string carefully(rather std::string should be used)
Thanks to all
If you are facing a SegFault I think this line could be the problem :
write("database",t);
because in your write function you use strcat on fname but you pass a read-only string.
Also, I think it might be best to use real c++ instead of c+ like :
#include <string>
#include <iostream>
#include <fstream>
void my_write(std::sting & fname, std::string & text) {
std::string file = fname + ".txt";
std::osftream w(file, std::ios::app);
w << text << "\n";
w.flush();
w.close();
}
int main() {
std::string t = "";
std::string id = "Its id";
std::string pass = "Its password";
std::string fname = "database";
int login = 1;
t = id + "\n" + pass;
my_write( fname, t);
}
I haven't test it but the idea is here.
Related
I have written a C++ Function which can be represented as below:
All it does is take a string (this is where it crashes) and reverse it.
#include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std;
int main()
{
cout<<"Enter a string: "<<endl;
char *str;
gets(str);
cout<<"Reversed String is: ";
for(int i=strlen(str)-1;i>=0;i--)
cout<<(str[i]);
return 0;
}
I guess there's some kind of memory access violation.
Any clue why this doesn't work?
Error: Segmentation fault (core dumped)
In c++ there is way more easier and less error prone solution to this problem via std::reverse from algorithm. Also its easier to use std::string.
#include <iostream>
#include <algorithm>
int main ()
{
std::string input;
std::cout << "Enter string to reverse: ";
std::cin >> input;
std::reverse(input.begin(),input.end());
std::cout << "Reversed string: " << input << std::endl;
return 0;
}
If you have to do it via char arrays, try this (you dont even need dynamic memory allocation)
#include <iostream>
#include <algorithm>
#include <cstring>
int main ()
{
char input[1024];
puts("Enter string to reverse: ");
fgets(input, 1024, stdin);
std::reverse(input, input + strlen(input));
printf("Reversed string: %s", input);
return 0;
}
Your code isn't c++ style and I recommend you take a look at the answer from Filip (https://stackoverflow.com/a/45903067/4386427)
I'll just address what goes wrong with your code.
When you do
char* str;
all you get is a pointer that can point to a char. You don't get any memory for holding a char. Further the value of the pointer variable str is uninitialized.
So when you do
strlen(str)
you read an uninitialized variable and try to treat this uninitialized value as a C-style string. That is undefined behavior and is very likely to cause a program crash.
You need to make sure that str is initialized before using it. As you want dynamic memory, you could do:
char *str;
str = new(char[100]); // Initialize str to point to a dynamic allocated
// char array with size 100
...
...
delete(str);
But again - I wouldn't use this style in c++ code
I've been doing programming challenges on coderbyte and while doing one, ran into an issue. I want to isolate a word from a string, do some checks on it and then move to another word. The code I'm going to post is supposed to take only the first word and print it out on the screen. When I run it, it doesn't print anything. I thought that maybe I did something wrong in the while loop so I did a simple test. Let's say my input is "This is a test sentence" and instead of word (in cout), I type word[0]. Then it prints "T" just fine. Can you find what the problem is?
#include <iostream>
#include <string>
using namespace std;
int Letters(string str) {
int i=0;
int len=str.length();
string word;
while(i<len){
if(isspace(str[i])){word[i]='\0'; break;}
word[i]=str[i];
i++;
}
cout<<word;
return 0;
}
int main() {
int test;
string str;
getline(cin, str);
test=Letters(str);
return 0;
}
string word;
is default constructed, which is empty initially. Inside while loop, you tried to do:
word[i] = str[i];
It means you tried to access memory that has not been allocated,resulting in undefined behavior.
Try:
word.append(str[i]);
You can use simpler way to get words from input in C++. It will help you to avoid errors in the future.
#include <iostream>
using namespace std;
int main()
{
string word;
while(cin >> word)
{
// "word" contains one word of input each time loop loops
cout << word << endl;
}
return 0;
}
I'm very new to c++, I can enter a name, but it doesn't display correctly. My tutor told me to research strings, and when I did none of it made any sense.
#include<stdio.h>
#include<string.h>
main()
{
char name;
printf("Hello stranger, what is your name?\n");
scanf("%c\n", &name);
system("PAUSE");
printf("\n\nWelcome to the Town of Falls Creek, %c\n",name);
}
In C++, we use std::string for sequences of characters. And we use std::cout and std::cin instead of printf and scanf
Be sure to look at this on internet, you will find a lot of resources.
char name;
scanf("%c\n", &name);
is a C-style approach to read a single character from standard input.
What you should do is:
#include <iostream>
#include <string>
...
std::string name;
if (std::cin >> name)
std::cout << "Hello " << name << "." << std::endl;
You used a char as the variable for the name.
char name;
This is where you need to uses string.
Btw: You code would look more like modern c++
if you would use std::cin instead of scanf.
char can take only single character like 'a', 'b' etc... So use string data type there.
It doesnt show you the total name because you are using char.
Instead of char use string.
#include<stdio.h>
#include<string.h>
#include<conio.h>
main()
{
std::string name;
printf("Hello stranger, what is your name?\n");
scanf("%s\n", &name);
getch();
printf("\n\nWelcome to the Town of Falls Creek, %s\n",name);
}
Enjoy coding!
I am working on a madlibs program using pointers. When I try to build it does so correctly, but I think their is some trouble with dynamically allocated array used to store the lines from the text file that is read in. The umber that goes in the array is a sentinel value in the file. I also left in the cout statements to show it store the information before the error .Can Any help? The error is the stack around "entries".
//here is my code so far
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
using namespace std;
void header();
//string play_again();
void read_game_file(string **entries, int *num_entries, string **story, int *num_lines);
//string get_user_input(string* entries, int * num_entries);
int main()
{
header();
cout<<endl<<endl;
int num_entries=(NULL);
int *num_lines=(NULL);
string *entries (NULL);
string *story (NULL);
read_game_file( &entries, &num_entries, &story, &*num_lines);
cout<<"doneszo"<<endl;
string get_user_input(string*entries, int * num_entries);
}
void header()
{
cout<<"Hello! Welcome to the game Madlibs."<<endl;
cout<<"The object of the game is to produce something that sounds totally ridiculous."<<endl;
cout<<"So don't think to hard about your answers."<<endl;
cout<<"At the top, you will see a bunch of word descriptions followed by blank spaces."<<endl;
cout<<"Type your word in the blanks. The words should match the descriptions on the left."<<endl;
cout<<"Enter no when you no longer wish to play. Enter yes to continue. Have a great laugh!"<<endl;
}
void read_game_file(string **entries, int *num_entries, string **story, int *num_lines)
{
//Ask user to input file name and opens file
ifstream mad_lib;
string file_name;
cout<<"Please enter the file name with extension: ";
cin>>file_name;
mad_lib.open(file_name);
//Checks to see that file name is valid if not ask for input again
if (!mad_lib)
{
cout<<"File could not be opened. Please try again"<<endl;
cout<<"Please enter the file name with extension: ";
cin>>file_name;
mad_lib.open(file_name);
}
int work;
string line;
mad_lib>>work;
num_entries=&work;
getline(mad_lib,line);
*entries=new string[*num_entries];
cout<<*num_entries<<endl;
string * entry;
for(int i=0; i<*num_entries; i++)
{
entry = new string;
getline(mad_lib,*entry);
entries[i]= entry;
cout<<*(entries[i])<<endl;
}
string work_2;
int work_3;
stringstream ss;
getline(mad_lib,work_2);
ss<<work_2;
ss>>work_3;
cout<<work_2<<endl;
num_lines=&work_3;
*story=new string[*num_lines];
string *entry_2;
for(int j=0; j<=*num_lines; j++)
{
entry_2=new string;
getline(mad_lib,*entry_2);
story[j]= entry_2;
cout<<*(story[j])<<endl;
}
}
Don't use pointers in function arguments until necessary.
Use pass by reference and const instead.
Another question to ask yourself - do you really want read_game_file to "fill" up some data in its arguments? Can you design it better? Here, you have a bunch of variables defined in main, and you expect read_game_file to "fill" them for you.
You should instead encapsulate this functionality within a class. Pass in the file name as argument to the class's ReadFile(const string& filename) method. All of this data should be in the class.
To solve your immediate problem (in the unclean way):
void read_game_file(string **entries, int *num_entries, string **story, int *num_lines);
should be
void read_game_file(vector<string>& entries, int& num_entries, vector<string>& story, int& num_lines);
int main()
{
header();
cout << endl << endl; // spaces help readability!
int num_entries = 0;
int num_lines = 0;
vector<string> entries;
vector<string> story;
read_game_file( &entries, &num_entries, &story, &*num_lines);
cout << "doneszo"<< endl;
string get_user_input(vector<string>& entries, int& num_entries);
}
Use vectors instead of arrays. They're elegant and clean to use.
I'll leave the function for you to complete.
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).