This is my code to read a file and store some lines from a position in the file and save it to an char array.
The code works fine , if i call getVNP() once in the main.
However when i try calling it the second time , I encounter a buffer overload error.
I tried searching , but I haven found a solution please help thanks.
#include <iostream> // library that contain basic input/output functions
#include <fstream> // library that contains file input/output functions
#include <string>
using namespace std;
void getVNP(std::string fileName, char* outStr)
{
int end;
int start;
char sWord[] = "Virtual";
char eWord[] = "[Default";
int position = 0; //this will be used incremental to fill characters in the array
int sWord_size = 0;
int eWord_size = 0;
//this loop is calculating the length of input word
for (int i = 0; sWord[i] != '\0'; i++)
{
sWord_size++;
}
for (int i = 0; eWord[i] != '\0'; i++)
{
eWord_size++;
}
fstream fin(fileName.c_str());
fin.seekg(0, fin.end);
int epos = fin.tellg();
fin.seekg(0, fin.beg);
cout << epos;
int array_size = epos; // define the size of character array
char * array = new char[array_size]; // allocating size an array
//opening an input stream for file test.txt
/*checking whether file could be opened or not. If file does not exist or don't have read permissions, file
stream could not be opened.*/
if (fin.is_open())
{
//file opened successfully so we are here
cout << "File Opened successfully!!!. Reading data from file into array" << endl;
//this loop run until end of file (eof) does not occur
while(!fin.eof() && position < array_size)
{
fin.get(array[position]); //reading one character from file to array
position++;
}
array[position - 1] = '\0'; //placing character array terminating character
//this loop is searching for the word in the array
for (int i = 0; array[i] != '\0'; i++)
{
for (int j = 0; sWord[j] != '\0' && j < 20 ; j++)
{
if (array[i] != sWord[j])
{
break;
}
else
{
i++;
if (sWord[j + 1] == '\0')
{
start = i-sWord_size+23;
}
}
}
}
for (int i = 0; array[i] != '\0'; i++)
{
for (int j = 0; eWord[j] != '\0' && j < 20 ; j++)
{
if (array[i] != eWord[j])
{
break;
}
else
{
i++;
if(eWord[j + 1] == '\0')
{
end = i-eWord_size - 11;
}
}
}
}
//take the start pos and the end pos text and put in string array s;
fin.seekg(start);
char *s = new char[end - start + 1];
fin.read(s, end - start);
s[end - start] = 0;
size_t len = strlen(s);
for(int i=0; i <len; ++i)
{
outStr[i] = s[i];
}
fin.close();
}
else //file could not be opened
{
cout << "File could not be opened." << endl;
}
getchar();
}
int main()
{
std::string FilePath;
std::string FilePath2;
char aConfig[] = " ";
char bConfig[] = " ";
std::cout << "Please enter a file path: ";
std::cin >> FilePath;
std::cout << "Please enter a second file path: ";
std::cin >> FilePath2;
getVNP(FilePath, aConfig);
cout << aConfig;
getVNP(FilePath2, bConfig);
cout << bConfig;
getchar();
return 0;
}
Your char aConfig[] is an array with 2 indices. The first one is the space and the second one \0 to indicate the end of the array.
If your path is longer than 1 letter, you should either dynamically allocate this, pass the function a std::string by reference, or use the MAX_PATH define (thought I recommend the std::string solution).
void getVNP(std::string fileName, std::string &outStr);
Also you should clean up if you allocate something with new. This is not java.
In main
char aConfig[] = " ";
creates array char[2] (space and null at the end). The second one (bConfig) creates another array char[2].
In getVNP
outStr[i] = s[i];
You are writing to this static array while you have only place for 2 characters.
Condider changing aConfig and bConfig to std::string or allocating bigger buffer (char aConfig[255];).
Related
It's my first question in stack overflow so if there is some mistakes sorry about that. I'm trying to fill a 2d char array and then access each letter. I complied my code, there is no error but when I try to run it doesn't work. Here it's my code.
#include<iostream>
#include<string>
#include<stdlib.h>
using namespace std;
int main() {
char ch[] = "Welcome text in a separate line.";
char strWords[5][7];
int counter = 0;
int a = 0;
for (int i = 0; i < sizeof(ch); i++) {
if (ch[i] == ' ') {
strWords[counter][a] = '\0';
counter++;
a = 0;
}
else
{
strWords[counter][a] += ch[i];
a++;
}
}
for (int i = 0; i <= 5; i++) {
for (int a = 0; a <= 7; a++) {
cout << strWords[i][a] << " ";
}
}
return 0;
}
A few things wrong with your code
int main() {
char ch[] = "Welcome text in a separate line.";
// char strWords[5][7]; <<<=== i would change to be larger that you need, just in case
char strWords[20][20];
int counter = 0;
int a = 0;
for (int i = 0; i < strlen(ch); i++) { // sizeof is wrong, you need strlen
if (ch[i] == ' ') {
strWords[counter][a] = '\0';
counter++;
a = 0;
}
else
{
//strWords[counter][a] += ch[i];
strWords[counter][a] = ch[i]; // you do not need to try to concatenate, you are already walking down the buffer with 'a'
a++;
}
}
for (int i = 0; i < counter; i++) { // use 'counter' as it has the number of lines
// since you 0 terminated the string you do not need to walk character by character
cout << strWords[i] << " ";
}
return 0;
}
You are also not detecting and terminating the last word (since there is no space after it). I will leave that to you. The code I show does not print the word 'line.'
You should really have tests to make sure you do not overflow the length or number of words.
Plus you should ideally use std::string and std::vector
Note - if, for experimentation, you do want to walk through char by char to output the strings you should look for the terminating '0' character and exit the inner loop
I'm trying to write a simple program which takes an array of chars, and spits it out backwards. I know there are plenty of other ways to shorten this using a library header function, but I wanted to do it using for loops just to get used to them.
#include<stdio.h>
#include<iostream>
using namespace std;
char string1[10];
int count = 0;
char stringy[10];
void enterString()
{
cout << "please enter a string: " << endl;
cin >> string1;
}
void stringCounter(const char stringLength[])
{
//initiate for loop i = 0
//if stringLength[i] does not does not equal 'i' then carry on
//increment i
for (int i = 0; stringLength[i] != '\0'; i++)
{
count++;
}
cout << "size of string is: " << count << endl;
}
void reverseString(int arraySize, char string2[])
{
int counter = 0;
for (int i = arraySize; i >= 0; string2[i--])
{
stringy[counter] = string2[i];
counter++;
}
stringy[count] = '\0';
cout << stringy << endl;
}
int main()
{
enterString();
stringCounter(string1);
reverseString(count, string1);
return 0;
}
This is the whole program. The program is failing in function reverseString. I can't work out how to successfully read the last index of the char array string2[] and copy it into the first index of char array stringy.
One, If the user enters a string more than 10 characters long then your enterString() function will access the array out of its bound, at cin>>string1. So better to use getline to make sure you don't read more than what your array can hold.
Two, with your current implementation the reverseString() function will write to the first element of the array with the null terminator character,if the arraySize<=10, and trying to display that string will not show you anything.
This:
cin >> string1;//will try to access the array out of its bound if user give more than it can hold,i.e 10 characters
...
for (int i = arraySize; i >= 0; string2[i--])
{
stringy[counter] = string2[i];//the first iteration will put the '\0' character as the first elements of stringy
counter++;
}
Should be changed to:
cin.getline(string1,10);//make sure to get not more than 10 characters,including the null terminator
.....
for (int i = arraySize-1; i >= 0; i--)
{
stringy[counter] = string2[i];
counter++;
}
There are many mistakes in your program. If this is the exact code you are compiling then it should throw many errors.
Following might help.
#include<iostream>
using namespace std;
void reverseString(int , char *);
int stringCounter(const char );
int stringCounter(const char stringLength[])
{
int count = 0;
for (int i = 0; stringLength[i] != '\0'; i++)
count++;
cout << "size of string is: " << count << endl;
return count;
}
void reverseString(int arraySize, char string2[])
{
int counter = 0;
char stringy[100];
for (int i = arraySize - 1; i >= 0; i--)
{
stringy[counter] = string2[i];
counter++;
}
stringy[counter] = '\0';
cout << stringy << endl;
}
int main()
{
char str[] = "string";
reverseString(stringCounter(str),str);
return 0;
}
This was the interview question:
How to convert Dogs like cats to cats like Dogs ?
My code shows: cats like cats. Where am I making the mistakes?
#include <iostream>
using namespace std;
int main()
{
char sentence[] = ("dogs like cats");
cout << sentence << endl;
int len = 0;
for (int i = 0; sentence[i] != '\0'; i++)
{
len++;
}
cout << len << endl;
char reverse[len];
int k = 0;
for (int j = len - 1; j >= 0; j--)
{
reverse[k] = sentence[j];
k++;
}
cout << reverse << endl;
int words = 0;
char str[len];
for (int l = 0; reverse[l] != '\0'; l++)
{
if (reverse[l] == ' ' || reverse[l] == '\0') // not sure about this part
{
for (int m = l; m >= 0; m--)
{
str[words] = reverse[m];
words++;
}
}
}
cout << str;
return 0;
}
I know you can do this using pointers, stack, vectors... but interviewer was not interested in that!
This is a fixed version of your sample code:
Your principal problem is that every time you found and ' ' or '\0' you copy the bytes of the reverse string from the beginning to that point. Example in loop 5 you copy from index 0-5 (stac) from reverse to str in reverse order, but in in loop 10 you copy from index 0-10 (stac ekil) from reverse to str in reverse order, until here you have already the printed result string ('cats like cats'), and the same in loop 15 all of this incrementing the index of str, in the last loop you are written pass the end of the valid memory of str (and because of that not printed as output).
You need to keep track when end the last word reversed to reverse only the actual word, and not the string from the beginning to the actual index.
You don't want to count the special character (' ' and '\0') in the reversing of the words, you would end with cats like\0dogs
Modified sample code provided:
#include <iostream>
using namespace std;
int main() {
char sentence[] = ("dogs like cats");
cout << sentence << endl;
int len = 0;
for (int i = 0; sentence[i] != '\0'; i++) {
len++;
}
cout << len << endl;
char reverse[len];
int k = 0;
for (int j = len - 1; j >= 0; j--) {
reverse[k] = sentence[j];
k++;
}
cout << reverse << endl;
int words = 0;
char str[len];
// change here added last_l to track the end of the last word reversed, moved
// the check of the end condition to the end of loop body for handling the \0
// case
for (int l = 0, last_l = 0; ; l++) {
if (reverse[l] == ' ' || reverse[l] == '\0')
{
for (int m = l - 1; m >= last_l; m--) { // change here, using last_t to
str[words] = reverse[m]; // only reverse the last word
words++; // without the split character
}
last_l = l + 1; // update the end of the last
// word reversed
str[words] = reverse[l]; // copy the split character
words++;
}
if (reverse[l] == '\0') // break the loop
break;
}
cout << str << endl;
return 0;
}
Some code, written with the restriction of using the most simple features of the language.
#include <iostream>
// reverse any block of text.
void reverse(char* left, char* right) {
while (left < right) {
char tmp = *left;
*left = *right;
*right = tmp;
left++;
right--;
}
}
int main() {
char sentence[] = "dogs like cats";
std::cout << sentence << std::endl;
// The same length calculation as sample code.
int len = 0;
for (int i = 0; sentence[i] != '\0'; i++) {
len++;
}
std::cout << len << std::endl;
// reverse all the text (ex: 'stac ekil sgod')
reverse(sentence, sentence + len - 1);
// reverse word by word.
char* end = sentence;
char* begin = sentence;
while (end < sentence + len) {
if (*end != ' ')
end++;
if (end == sentence + len || *end == ' ') {
reverse(begin, end - 1);
begin = end + 1;
end = begin;
}
}
std::cout << sentence << std::endl;
return 0;
}
Dissecting your algorithm in pieces. First, you find the length of the string, not including the null char terminator. This is correct, though could be simplified.
size_t len = 0;
for (int i = 0; sentence[i] != '\0'; i++) {
len++;
}
cout << len << endl;
This could easily be written simply as:
size_t len = 0;
while (sentence[len])
++len;
Next, you reverse the entire string, but the first defect surfaces. The VLA (variable length array) you declare here, (which you don't need and shouldn't use, as it is a C++ extension and non-standard) does not account for, nor set, a terminating null-char.
char reverse[len]; // !! should be len+1
int k = 0;
for (int j = len - 1; j >= 0; j--) {
reverse[k] = sentence[j];
k++;
}
// !! Should have reverse[k] = 0; here.
cout << reverse << endl; // !! Undefined-behavior. no terminator.
This temporary buffer string is not needed at all. There is no reason you can't do this entire operation in-place. Once we calculate len correctly, you simply do something like the following to reverse the entire sequence, which retains the null char terminator in proper position:
// reverse entire sequence
int i = 0, j = len;
while (i < j--)
{
char c = sentence[i];
sentence[i++] = sentence[j];
sentence[j] = c;
}
Next we move to where you try to reverse each internal word. Again, just as before, the buffer length is not correct. It should be len+1. Worse (hard to imagine), you never remember where you left off when finding the end point of a word. That location should be the next point you start checking for, and skipping, whitespace. Without retaining that you copy from current point all the way back to the beginning of the string. which essentially blasts cats over dogs.
int words = 0;
char str[len]; // !! should be len+1
for (int l = 0; reverse[l] != '\0'; l++)
{
if (reverse[l] == ' ' || reverse[l] == '\0') // not sure about this part
{
for (int m = l; m >= 0; m--) {
str[words] = reverse[m];
words++;
}
}
}
cout << str; //!! Undefined behavior. non-terminated string.
Once again, this can be done in-place without difficulty at all. One such algorithm looks like this (and notice the loop that reverses the actual word is not-coincidentally the same algorithm as reversing our entire buffer):
// walk again, reversing each word.
i = 0;
while (sentence[i])
{
// skip ws; root 'i' at beginning of word
while (sentence[i] == ' ') // or use std::isspace(sentence[i])
++i;
// skip until ws or eos; root 'j' at one-past end of word
j = i;
while (sentence[j] && sentence[j] != ' ') // or use !std::isspace(sentence[j])
++j;
// remember the last position
size_t last = j;
// same reversal algorithm we had before
while (i < j--)
{
char c = sentence[i];
sentence[i++] = sentence[j];
sentence[j] = c;
}
// start at the termination point where we last stopped
i = last;
}
Putting It All Together
Though considerably simpler to use pointers than all these index variables, the following will do what you're attempting, in place.
#include <iostream>
int main()
{
char s[] = "dogs like cats";
std::cout << s << '\n';
size_t len = 0, i, j;
while (s[len])
++len;
// reverse entire sequence
i = 0, j = len;
while (i < j--)
{
char c = s[i]; // or use std::swap
s[i++] = s[j];
s[j] = c;
}
// walk again, reversing each word.
i = 0;
while (s[i])
{
// skip ws; root 'i' at beginning of word
while (s[i] == ' ') // or use std::isspace
++i;
// skip until ws or eos; root 'j' at one-past end of word
j = i;
while (s[j] && s[j] != ' ') // or use !std::isspace
++j;
// remember the last position
size_t last = j;
while (i < j--)
{
char c = s[i]; // or use std::swap
s[i++] = s[j];
s[j] = c;
}
// start at last-left posiion
i = last;
}
std::cout << s << '\n';
return 0;
}
Output
dogs like cats
cats like dogs
My advise would be to break up the original string into an array of words, reverse that array. Then add those words to your reversed sentence with a space in between.
Since they asked for no libraries, I assumed no std::string, no vectors, nothing at all and so I wrote it in C.. the only thing used is printf. Everything else is from scratch :l
The idea is that you reverse the array first. Then split the array by space and reverse each word.
Example: http://ideone.com/io6Bh9
Code:
#include <stdio.h>
int strlen(const char* s)
{
int l = 0;
while (*s++) ++l;
return l;
}
void reverse(char* str)
{
int i = 0, j = strlen(str) - 1;
for(; i < j; ++i, --j)
{
str[i] ^= str[j];
str[j] ^= str[i];
str[i] ^= str[j];
}
}
void nulltok(char* str, char tok, int* parts)
{
int i = 0, len = strlen(str);
*parts = 1;
for (; i < len; ++i)
{
if (str[i] == tok)
{
str[i] = '\0';
++(*parts);
}
}
}
char* reverse_sentence(char* str)
{
char* tmp = str;
reverse(str);
int i = 0, parts = 0, len = strlen(str);
nulltok(str, 0x20, &parts);
while(parts--)
{
reverse(str);
str += strlen(str) + 1;
}
for(; i < len; ++i)
if (tmp[i] == '\0')
tmp[i] = 0x20;
return tmp;
}
int main(void)
{
char str[] = "dogs like cats";
printf("%s", reverse_sentence(str));
return 0;
}
My solution
#include<iostream>
#include<string.h>
using namespace std;
int main()
{
string str;
cout<<"enter the sentence"<<endl;
getline(cin,str);
char* pch;
pch = strtok((char*)str.c_str()," ");
string rev = "";
while(NULL != pch)
{
rev.insert(0,pch);
rev.insert(0," ");
pch = strtok(NULL," ");
}
cout<<"the reversed string is :"<<rev<<endl;
return 0;
}
The purpose of the following code was to create an strcat function using only basic array manipulation. A destination char array is input by a user and a source char array is appended to the end of it. My code works mostly fine except for the random chars it spits out for certain input char arrays. For example if I have my destination input as cheese and my source input as burger, the output is cheeseburger, as it should be. However if my destination input is dragon and my source input is fly, dragonfly should be the output. However, the output is given as dragonfly#. I have no idea what's wrong, and need help.
#include <iostream>
#include <string>
using namespace std;
void mystrcat ( char destination[], const char source[]);
int main(){
char source[80];
char destination[80];
cout << "Enter a word: ";
cin >> source;
cout << "\n";
cout << "Enter a second word: ";
cin >> destination;
mystrcat(destination, source);
}
void mystrcat ( char destination[], const char source[]){
int x=0;
for(int i=0; destination[i] != '\0'; i++)
{
if ( destination[i] != '\0')
{
x = x + 1;
}
}
for(int i=0; source[i] != '\0'; i++)
{
destination[i + x] = source[i];
}
cout << destination << endl;
}
Basically, you just need to add a null-character ('\0') at the end of the destination array.
Here is the correct (and slightly simplified) implementation:
void mystrcat(char destination[], const char source[])
{
int x = 0;
while (destination[x] != '\0')
{
x++;
}
for (int i=0; source[i] != '\0'; i++)
{
destination[x++] = source[i];
}
destination[x] = '\0';
}
But you should be aware that you have no safety-assertion on the size of the destination array...
You don't terminate the destination string. You need to add the '\0' character at the end.
short code:
void _mystrcat_(
__in char * out,
__in char * in)
{
while (*out) out++;
do { *out++ = *in++; } while (*in);
*out = 0x0;
}
I'm writing a program that requires a string to be inputted, then broken up into individual letters. Essentially, I need help finding a way to turn "string" into ["s","t","r","i","n","g"]. The strings are also stored using the string data type instead of just an array of chars by default. I would like to keep it that way and avoid char but will use it if necessary.
Assuming you already have the string inputted:
string s("string");
vector<char> v(s.begin(), s.end());
This will fill the vector v with the characters from a string.
string a = "hello";
cout << a[1];
I hope that explains it
A string is just a sequence of the underlying character (i.e. char for std::string and wchar_t for std::wstring).
Because of that, you easily get each letter:
for (std::string::size_type l = 0; l < str.length(); ++l)
{
std::string::value_type c = str[l];
}
Try using the c_str() method of std::string:
#include <string>
using namespace std;
int main(void)
{
string text = "hello";
size_t length = text.length() + sizeof('\0');
char * letters = new char[length];
strcpy(letters, length.c_str());
for (unsigned int i = 0; i < length; ++i)
{
cout << '[' << i << "] == '" << letters[i] << "'\n";
}
return EXIT_SUCCESS;
}
string input ="some string for example my cat is handsome";
vector<string> split_char_to_vector(string input) {
vector<string> output;
for(size_t i=0;i<=input.length();i++) {
output.push_back(input[i]));
}
return output;
}
if you want to convert split strings into character the first traverse the string and write for each characters of string to the i'th position of char array ie
char array[1000];
std::string input="i dont think love never ends";
for(size_t i=0;i<=input.length();/*or string::npos;*/i++)
{
if (input[i] != '\0')
{
array[i] = input[i];
}
else
{
break;
}
}
for (size_t i = 0; i < 100; i++)
{
std::cout << array[i] << std::endl;
}
if you want to convert split strings into character the first traverse the string and write for each characters of string to the i'th position of char array ie
char array[1000];
std::string input="i dont think love never ends";
for(size_t i=0;i<=input.length();/*or string::npos;*/i++)
{
if (input[i] != '\0')
{
array[i] = input[i];
}
else
{
break;
}
}
//to avoid noise after position input.length();
for (size_t i = input.length(); i <= 1000; i++)
{
array[i] = '\0';
}
//ie return array; or print
for (size_t i = 0; i < 100; i++)
{
std::cout << array[i] << std::endl;
}
You can use a for loop to iterate through the characters of a string.
std::string str = "word"
for(char i : str){
std::cout << i << std::endl;
}