Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 8 years ago.
Improve this question
this is my code
#include <unistd.h>
#include <sys/types.h>
#include <dirent.h>
#include <stdio.h>
#include <cstring>
#include <iostream>
using namespace std;
bool endsWith(string const &value, string const &ending)
{
if(value.length() >= ending.length())
{
return (value.compare(value.length() - ending.length(), ending.length(), ending) == 0);
}
return false;
}
void listdir(const char *directory, const char *extension)
{
DIR *dir;
struct dirent *entry;
if(!(dir = opendir(directory)))
{
return;
}
while(entry = readdir(dir))
{
if(entry->d_type == DT_DIR)
{
char path[1024];
int len = snprintf(path, sizeof(path)-1, "%s/%s", directory, entry->d_name);
path[len] = 0;
if(strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0)
{
listdir(path, extension);
}
}
else
{
string file = entry->d_name;
if(endsWith(file, strcat((char *) ".", extension)) || extension == "*")
{
printf("%s \n", entry->d_name);
}
}
}
closedir(dir);
}
int main(int count, char *parameters[])
{
const char *type = "*";
const char *path = ".";
if(count > 1)
{
path = parameters[1];
}
if(count > 2)
{
type = parameters[2];
}
if(count < 1 || count > 3)
{
return 0;
}
listdir(path, type);
return 0;
}
And no matter, what i am doing, i always receive segmentation fault.
Compiling it with g++ under debian is no problem, but running the application puts out always "Segmentation fault"
So what's the matter?
Your error lies in the line strcat((char *) ".", extension), where you try to write data to the memory underlying a string literal.
String literals are loaded into a read only memory segment and trying to write to that causes your segfault.
If you wish to use strcat, you have to provide a target buffer of sufficient size (which is not checked, so using strncat is often preferred). Since this size is undetermined at compile time, you are forced to compute the length of the two strings you wish to append to one another and allocate a buffer of sufficient size with new or malloc.
However, the easiest way of performing a string concatenation in C++ is to forget all about the C equivalents and simply use ::std::string like so:
::std::string s = "hello ";
s += "world";
Related
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 7 days ago.
Improve this question
So I have this strcpy with tables but I need to change it so that there's no tables and only pointers. When I try to do it, there's an error (I put $$ in front)
So the original:
#include <iostream>
using namespace std;
int main() {
char *mon_strcpy(char destination[], char source[]) {
int index = 0;
while (source[index] != '\0') {
destination[index] = source[index];
index++;
}
destination[index] = '\0';
return destination;
}
return 0;
}
And this is the one I'm trying to make it work:
#include <iostream>
using namespace std;
int main() {
char *mon_strcpy(char *destination, char *source) $${
int index = 0;
while (*source != '\0')
{
*destination = *source;
index++;
}
*destination = '\0';
return destination;
}
return 0;
}
I can't wrap my head around to find the problem.. TIA
In C & C++, you have to declare-define a function outside the other function (here main()). Something like:
char *mon_strcpy(char *destination, char *source) { ... }
int main () {
mon_strcpy(dst, src);
}
Also $$ sign is not allowed to be used inside C++ code except comments.
This just addresses the compiler error you have.
If you have a problem with the function logic, why is it not working? You may want to debug followed by a new question.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 28 days ago.
Improve this question
The following code outputs the correct string in the parameters function, but the incorrect string in main.
Obviously something is going wrong, but I can't see what it is. Thanks.
#include <iostream>
#include <string>
using namespace std;
typedef struct sim {
const char* dir;
} sim;
string convertToString(char* a)
{
string s(a);
return s;
}
int parameters(sim *sdata, char **argv, int argc){
char *filename;
string token;
string delimiter = "=";
size_t pos = 0;
string s;
for (int i = 0; i < argc; ++i){
s = convertToString(argv[i]);
while ((pos = s.find(delimiter)) != string::npos) {
token = s.substr(0, pos);
s.erase(0, pos + delimiter.length());
}
if(token == "-dir"){
sdata->dir = s.c_str();
cout << sdata->dir << endl;
}
}
}
int main(int argc, char** argv) {
sim * sdata = (sim*)malloc(sizeof(sim));
parameters(sdata, argv, argc);
cout << sdata->dir << endl;
free(sdata);
return 0;
}
I started the program with ./teststring -dir=/home/stephen and got:
/home/stephen
�a
I was expecting both outputs to be the same.
The program has undefined behavior.
The pointer sdata->dir will be invalid after exiting the function parameters because the object s will not be alive. It has only the block scope of the function.
Also use the operators new and delete instead of calling the C function malloc. So write
sim * sdata = new sim;
You could write within the function for example like
if ( token == "-dir" )
{
sdata->dir = new char[s.length() + 1 ];
strcpy( sdata->dir, s.c_str() );
cout << sdata->dir << endl;
}
else
{
sdata->dir = nullptr;
}
provided that the data member dir is declared without the qualifier const.
typedef struct sim {
char* dir;
} sim;
Also using the typedef specifier in the structure declaration is redundant in C++.
So in main you will need to write
delete [] sdata->dir;
delete sdata;
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
What I am trying to do is to parse a csv file into a dynamically allocated part of a memory that represents an array of instances of a class called rectangle.
The project consists of the following files:
rectStructs.h:
#pragma once
struct rectangle_t
{
int length;
int width;
};
rectangles.h
#pragma once
#include <iostream>
#include "rectStructs.h"
using namespace std;
class rectangle
{
public:
rectangle(int length, int width);
unsigned long int get_area();
private:
rectangle_t _rectangle;
};
rectangles.cpp
#include "rectangles.h"
#include <string>
rectangle::rectangle(int RectLength, int RectWidth)
{
_rectangle.length = RectLength;
_rectangle.width = RectWidth;
}
unsigned long int rectangle::get_area()
{
return _rectangle.length * _rectangle.width;
}
rectanglesSet.h
#pragma once
#include "rectangles.h"
#include <iostream>
#include <fstream>
class rectangleSet
{
public:
rectangleSet(string path_sourceCSV);
rectangle getRect(unsigned int RectIndex);
private:
void readRectsFromCSV(rectangle** rectangles, string path_sourceCSV);
rectangle* _rectangles;
unsigned int _rectCount;
rectangle _getRect(rectangle** rectangles, unsigned int RectIndex);
};
rectanglesSet.cpp
#define _CRT_SECURE_NO_DEPRECATE // For using fopen and strtok https://stackoverflow.com/questions/42412372/error-c4996-visual-studio-why-do-i-get-an-error-when-i-use-fopen-in-c
#include "rectanglesSet.h"
void rectangleSet::readRectsFromCSV(rectangle** rectangles, string path_sourceCSV)
{
unsigned short int _linesCount = 0;
//Parsing lt. https://stackoverflow.com/questions/56783258/parse-csv-into-dynamically-allocated-array-of-structures-ansi-89
char c;
FILE* fp;
fp = fopen(path_sourceCSV.c_str(), "r"); /* Open the saleslines file */
if (fp == NULL) { /* Crash if file not found */
printf("Error - file not found\n");
}
c = getc(fp);
while (c != EOF) {
if (c == '\n') {
_linesCount++;
}
c = getc(fp);
}
fclose(fp);
cout << "Number of lines: " << _linesCount << endl; //Debug
*rectangles = (rectangle*)malloc((_linesCount + 1) * sizeof(rectangle));
int _length;
int _width;
/* allocation of the buffer for every line in the File */
char buf[1024];
string tmp;
if ((fp = fopen(path_sourceCSV.c_str(), "r")) == NULL)
{
printf("File could not be opened.\n");
}
int line = 0;
while (fgets(buf, 1024, fp) != NULL)
{
if ((strlen(buf) > 0) && (buf[strlen(buf) - 1] == '\n'))
buf[strlen(buf) - 1] = '\0';
if (line > 0) // First line is header
{
tmp = strtok(buf, ",");
_length = atoi(tmp.c_str());
tmp = strtok(NULL, ",");
_width = atoi(tmp.c_str());
rectangles[line - 1] = new rectangle(_length, _width);
//Debug
cout << rectangles[line - 1]->get_area() << endl;
}
line++;
}
fclose(fp);
//_rectCount = line - 1;
cout << "Successfully parsed: " << path_sourceCSV << endl;
}
rectangleSet::rectangleSet(string path_sourceCSV)
{
readRectsFromCSV(&_rectangles, path_sourceCSV);
}
rectangle rectangleSet::_getRect(rectangle** rectangles, unsigned int rectIndex)
{
return *rectangles[rectIndex];
}
rectangle rectangleSet::getRect(unsigned int rectIndex)
{
return _getRect(&_rectangles, rectIndex);
}
main.cpp
#include <iostream>
#include "rectangles.h"
#include "rectanglesSet.h"
int main()
{
string str_SourceCSV = "C:\\rectangleList.csv";
rectangleSet* _rectangleSet = new rectangleSet(str_SourceCSV);
cout << _rectangleSet->getRect(1).get_area() << endl;
}
C:\rectangleList.csv
x,y
1,2
3,4
5,6
Everything works perfectly fine, as long as I comment out the following line in the file rectanglesSet.cpp
//_rectCount = line - 1;
It is supposed to write a private variable holding the number of items in the dynamic array _rectangles. When I uncomment this line the program crashes with a memory error. It runs to the point of displaying the second item ([1]) of the object _rectangleSet.
What is wrong with this line?
_rectCount = line - 1;
You are allocating an array of rectangles here
*rectangles = (rectangle*)malloc((_linesCount + 1) * sizeof(rectangle));
but then you are treating it as if you had an array of rectangle pointers here
rectangles[line - 1] = new rectangle(_length, _width);
The correct code for the above line is
(*rectangles)[line - 1] = rectangle(_length, _width);
However even with this fix you are still technically wrong because the above line assigns to uninitialised memory (returned by malloc). So the first line should really be using new instead to make sure the rectangle array is properly initialised.
*rectangles = new rectangle[_linesCount + 1];
C++ is a lot easier if you don't try to do your own memory management. Instead of the above code I recommend that you use std::vector<rectangle>. It would be a lot more efficient as well, because you could use the vector::push_back method so you don't have to precalculate the number of lines and so you avoid reading the input file twice.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 5 years ago.
Improve this question
I am supposed to write a program that takes in string like "pre#ogrann##mmink#g" and returns "programming", it is like your backspace button is broken and when you hit it you get '#' instead of erasing the char out, and I have to fix it. I have working code here under but it is way to slow, and I might have to deal with huge string, any suggestion how I could do it better/faster?
#include <string>
#include <iostream>
using namespace std;
int main() {
string str;
while(cin >> str) {
bool done = false;
while(!done) {
if((int)str.find('#')>-1) {
str.erase(str.find('#')-1, 2);
} else {
done = true;
}
}
cout << str << endl;
}
}
Here's how I would do it. I haven't tested it to see if it is actually faster, but as it has a complexity of O(N), I think it should be fast enough:
while (std::cin >> input) {
std::string result;
result.reserve(input.length());
for (auto ch : input) {
if (ch == '#') {
if (result.length() > 0)
result.pop_back();
continue;
}
result += ch;
}
std::cout << result << '\n';
}
#include <iostream>
#include <string>
using namespace std;
string s = "pre#ogrann##mmink#g";
int main() {
string out;
int len = s.length();
for (int i = 0; i < len; i++) {
if(s[i] == '#') {
s.erase(i-1,2);
len = s.length();
i -= 2;
}
}
cout << s;
return 0;
}
This produces a working output.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I don't understand why this won't run properly in Visual Studio 2012
#include <iostream>
#include <cstring>
#include <cstdlib>
using namespace std;
char nullChar()
{
char ch;
int ran = (rand() % 52);
if (ran < 26)
{
ch = (char) ('a'+ ran);
}
else
{
ch = (char) ('A'+ ran - 26);
}
return ch;
}
int main(int argc, char *argv[])
{
cout << "Enter a string";
int nullNum = 0;
nullNum = atoi(argv[2]);
if (strcmp(argv[1], "-d") == 0)
{
int count = -1;
do
{
int c = cin.get();
count++;
if(count == nullNum)
{
cout.put(c);
count = -1;
}
} while (!cin.eof()) ;
}
if(strcmp(argv[1], "-e") == 0)
{
char c = cin.get();
while(!cin.eof())
{
for (int i = -1; i < (nullNum-1); ++i)
{
cout << nullChar();
}
cout << c;
c = cin.get();
}
}
}
The code compiles perfectly. I'm suspecting something in a loop but I can't figure it out. I also think it ran perfectly a few days ago but now it's not. Is that possible?
Im not sure if you passed a parameter. But aside from that you should always check argc before using argv[xyz]. My guess is you get a segfault, because there is no argv[1] and argv[2]