By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,007 Members | 1,023 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,007 IT Pros & Developers. It's quick & easy.

[C++] Segmentation Fault {C++ Novice Programmer}

P: n/a
Hello guys.

I have a function, cleanSpace [which takes in a string such as
"this is\ta\ta a test". It cleans it up by removing new
lines/tabs and multiple/trailing and inbetween whitespace. I am
recieving a segmentation fault on one line when I apply it to a second
program [my second school assignment]. I was told from another source
that the problem is, is that the function is acting on constant string
literal. To fix this I was told to take the incoming string, copy it to
a buffer, work on the buffer and copy the buffer back to the original.
I tried but no sucess.

The seg fault is shown after the code snippet below.
int Account::cleanSpace(char c[])
{
int i=0,
j=0,
k=0,
m=0;

/* Ultimately this loop will scan for new lines and tabs and replace
them
with spaces. */
for(i=0; c[i]; i++)
{
if(c[i] == '\n' || c[i] == '\t')
c[i] = ' ';
}

/* For loop finds character starting point. */
for(i=0; c[i] == ' '; i++)
{
c[m] = c[i+1];
}

/* For loop moves all characters next to the first found character.
*/
for(i++; c[i]; i++)
{
c[++m] = c[i];
}

/* For loop removes trailing spaces. */
for(i = strlen(c) - 1; c[i] == ' '; i--)
{
c[i] = '\0';
}

/*For loop removes excess spaces. */
for(i = 0; c[i]; i++)
{
if(c[i] == ' ' && c[i+1] == ' ')
{
j = i;

while(c[j] == ' ')
{
j++;
}

for(k = i + 1; c[k]; k++, j++)
{
c[k] = c[j];
}
j=0;
}
}
return strlen(c);
}
Here is the function that calls it
int Account::changeCustomerInfo(char c[])
{
int result = 0;
char temp[251];
result = strlen(c) - 250;

cleanSpace(c); //Calls the cleanSpace function

if(strlen(c) <= 250){
strcpy(this->customer, c);
}
else{
for(int i = 0; i < 250; i++){
temp[i] = c[i];
}
strcpy(this->customer, temp);}

if(strlen(c) > 250){
return result;}

else return 0;
}
I recieve the seg fault on this code snippet below [which is found in
the cleanSpace function]

/* For loop moves all characters next to the first found character.
*/
for(i++; c[i]; i++)
{
c[++m] = c[i];
}

So by working with
int Account::cleanSpace(char c[]) function, how can I make it work not
on a string literal.

Thanks in advance. Appreciate any help whatsoever.

Jul 23 '05 #1
Share this Question
Share on Google+
6 Replies


P: n/a

"AMT2K5" <Aa*********@gmail.com> wrote in message
news:11********************@g49g2000cwa.googlegrou ps.com...
Hello guys.

I have a function, cleanSpace [which takes in a string such as
"this is\ta\ta a test". It cleans it up by removing new
lines/tabs and multiple/trailing and inbetween whitespace. I am
recieving a segmentation fault on one line when I apply it to a second
program [my second school assignment]. I was told from another source
that the problem is, is that the function is acting on constant string
literal. To fix this I was told to take the incoming string, copy it to
a buffer, work on the buffer and copy the buffer back to the original.
I tried but no sucess.

The seg fault is shown after the code snippet below.
int Account::cleanSpace(char c[])
{
int i=0,
j=0,
k=0,
m=0;

/* Ultimately this loop will scan for new lines and tabs and replace
them
with spaces. */
for(i=0; c[i]; i++)
{
if(c[i] == '\n' || c[i] == '\t')
c[i] = ' ';
}

/* For loop finds character starting point. */
for(i=0; c[i] == ' '; i++)
{
c[m] = c[i+1];
}

/* For loop moves all characters next to the first found character.
*/
for(i++; c[i]; i++)
{
c[++m] = c[i];
}

/* For loop removes trailing spaces. */
for(i = strlen(c) - 1; c[i] == ' '; i--)
{
c[i] = '\0';
}

/*For loop removes excess spaces. */
for(i = 0; c[i]; i++)
{
if(c[i] == ' ' && c[i+1] == ' ')
{
j = i;

while(c[j] == ' ')
{
j++;
}

for(k = i + 1; c[k]; k++, j++)
{
c[k] = c[j];
}
j=0;
}
}
return strlen(c);
}
Here is the function that calls it
int Account::changeCustomerInfo(char c[])
{
int result = 0;
char temp[251];
result = strlen(c) - 250;

cleanSpace(c); //Calls the cleanSpace function

if(strlen(c) <= 250){
strcpy(this->customer, c);
}
else{
for(int i = 0; i < 250; i++){
temp[i] = c[i];
}
strcpy(this->customer, temp);}

if(strlen(c) > 250){
return result;}

else return 0;
}
I recieve the seg fault on this code snippet below [which is found in
the cleanSpace function]

/* For loop moves all characters next to the first found character.
*/
for(i++; c[i]; i++)
{
c[++m] = c[i];
}

So by working with
int Account::cleanSpace(char c[]) function, how can I make it work not
on a string literal.

Thanks in advance. Appreciate any help whatsoever.


I didn't throughly analyze all conditions, but on the strings "XXX\t\n" and
" X ", it worked fine for me. (I substituted the member customer for a
local char[500] array, and made the functions global, but that shouldn't
affect things unless you've got other problems in the class that end up
causing this crash sometime later.) You should try debugging the app and
seeing what the values of c,i and m are the time it crashes. Perhaps
there's some condition you're not accounting for properly.

-Howard

Jul 23 '05 #2

P: n/a

"AMT2K5" <Aa*********@gmail.com> wrote in message
news:11********************@g49g2000cwa.googlegrou ps.com...
Hello guys.

I have a function, cleanSpace [which takes in a string such as
"this is\ta\ta a test". It cleans it up by removing new
lines/tabs and multiple/trailing and inbetween whitespace. I am
recieving a segmentation fault on one line when I apply it to a second
program [my second school assignment]. I was told from another source
that the problem is, is that the function is acting on constant string
literal. To fix this I was told to take the incoming string, copy it to
a buffer, work on the buffer and copy the buffer back to the original.
I tried but no sucess.

The seg fault is shown after the code snippet below.
int Account::cleanSpace(char c[])
{
int i=0,
j=0,
k=0,
m=0;

/* Ultimately this loop will scan for new lines and tabs and replace
them
with spaces. */
for(i=0; c[i]; i++)
{
if(c[i] == '\n' || c[i] == '\t')
c[i] = ' ';
}

/* For loop finds character starting point. */
for(i=0; c[i] == ' '; i++)
{
c[m] = c[i+1];
}

/* For loop moves all characters next to the first found character.
*/
for(i++; c[i]; i++)
{
c[++m] = c[i];
}

/* For loop removes trailing spaces. */
for(i = strlen(c) - 1; c[i] == ' '; i--)
{
c[i] = '\0';
}

/*For loop removes excess spaces. */
for(i = 0; c[i]; i++)
{
if(c[i] == ' ' && c[i+1] == ' ')
{
j = i;

while(c[j] == ' ')
{
j++;
}

for(k = i + 1; c[k]; k++, j++)
{
c[k] = c[j];
}
j=0;
}
}
return strlen(c);
}
Here is the function that calls it
int Account::changeCustomerInfo(char c[])
{
int result = 0;
char temp[251];
result = strlen(c) - 250;

cleanSpace(c); //Calls the cleanSpace function

if(strlen(c) <= 250){
strcpy(this->customer, c);
}
else{
for(int i = 0; i < 250; i++){
temp[i] = c[i];
}
strcpy(this->customer, temp);}

if(strlen(c) > 250){
return result;}

else return 0;
}
I recieve the seg fault on this code snippet below [which is found in
the cleanSpace function]

/* For loop moves all characters next to the first found character.
*/
for(i++; c[i]; i++)
{
c[++m] = c[i];
}

So by working with
int Account::cleanSpace(char c[]) function, how can I make it work not
on a string literal.

Thanks in advance. Appreciate any help whatsoever.


I'm taking C and C++ classes right now. The cpp file I attached contains a
program I wrote using C to take user input from the keyboard (whether it's
got letters, numbers, spaces, or other characters), strips all
non-alphabetic characters, removes all spaces, and puts it back into a
sentence. Of course the requirement for this particular program was to
translate English into Pig Latin, so it does some things you don't want.

I make no guarantees about the code (I'm still learning, too). You'll
notice it's in a cpp file and not a c file because I kept getting memory
errors from the executable when using Dev-C++; those errors went away when I
compiled it in an empty VisualC++ project. Maybe somebody else could point
out why.

Dave


Jul 23 '05 #3

P: n/a
>>I was told from another source
that the problem is, is that the function is acting on constant string
literal. To fix this I was told to take the incoming string, copy it to
a buffer, work on the buffer and copy the buffer back to the original.

I think you didn't fix problem right.

You are still working on const string.

Fix:

You are actually making copy of string into "temp". But you are not
passing temp to "changeCustomerInfo()". You are still passing "c" to
"changeCustomerInfo()". "c" is const string, that is why the crash.

Instead you should pass "temp"

-Nagarajan Makala

Howard wrote: "AMT2K5" <Aa*********@gmail.com> wrote in message
news:11********************@g49g2000cwa.googlegrou ps.com...
Hello guys.

I have a function, cleanSpace [which takes in a string such as
"this is\ta\ta a test". It cleans it up by removing new
lines/tabs and multiple/trailing and inbetween whitespace. I am
recieving a segmentation fault on one line when I apply it to a second
program [my second school assignment]. I was told from another source
that the problem is, is that the function is acting on constant string
literal. To fix this I was told to take the incoming string, copy it to
a buffer, work on the buffer and copy the buffer back to the original.
I tried but no sucess.

The seg fault is shown after the code snippet below.
int Account::cleanSpace(char c[])
{
int i=0,
j=0,
k=0,
m=0;

/* Ultimately this loop will scan for new lines and tabs and replace
them
with spaces. */
for(i=0; c[i]; i++)
{
if(c[i] == '\n' || c[i] == '\t')
c[i] = ' ';
}

/* For loop finds character starting point. */
for(i=0; c[i] == ' '; i++)
{
c[m] = c[i+1];
}

/* For loop moves all characters next to the first found character.
*/
for(i++; c[i]; i++)
{
c[++m] = c[i];
}

/* For loop removes trailing spaces. */
for(i = strlen(c) - 1; c[i] == ' '; i--)
{
c[i] = '\0';
}

/*For loop removes excess spaces. */
for(i = 0; c[i]; i++)
{
if(c[i] == ' ' && c[i+1] == ' ')
{
j = i;

while(c[j] == ' ')
{
j++;
}

for(k = i + 1; c[k]; k++, j++)
{
c[k] = c[j];
}
j=0;
}
}
return strlen(c);
}
Here is the function that calls it
int Account::changeCustomerInfo(char c[])
{
int result = 0;
char temp[251];
result = strlen(c) - 250;

cleanSpace(c); //Calls the cleanSpace function

if(strlen(c) <= 250){
strcpy(this->customer, c);
}
else{
for(int i = 0; i < 250; i++){
temp[i] = c[i];
}
strcpy(this->customer, temp);}

if(strlen(c) > 250){
return result;}

else return 0;
}
I recieve the seg fault on this code snippet below [which is found in
the cleanSpace function]

/* For loop moves all characters next to the first found character.
*/
for(i++; c[i]; i++)
{
c[++m] = c[i];
}

So by working with
int Account::cleanSpace(char c[]) function, how can I make it work not
on a string literal.

Thanks in advance. Appreciate any help whatsoever.


I didn't throughly analyze all conditions, but on the strings "XXX\t\n" and
" X ", it worked fine for me. (I substituted the member customer for a
local char[500] array, and made the functions global, but that shouldn't
affect things unless you've got other problems in the class that end up
causing this crash sometime later.) You should try debugging the app and
seeing what the values of c,i and m are the time it crashes. Perhaps
there's some condition you're not accounting for properly.

-Howard


Jul 23 '05 #4

P: n/a
That makes sense, thanks. Although I am unsure where I would declare
and state what temp is.

Original call
void Account::init(char c[], char num[], int b)
{
changeCustomerInfo(c);
changeAccountNumber(num);
changeBalance(b);
}

I cant do the following though, because temp would just be empty.

void Account::init(char c[], char num[], int b)
{
char temp[300];

changeCustomerInfo(temp);
changeAccountNumber(num);
changeBalance(b);
}
What am I overlooking here?

Nagarajan Makala wrote:
I was told from another source
that the problem is, is that the function is acting on constant string
literal. To fix this I was told to take the incoming string, copy it to
a buffer, work on the buffer and copy the buffer back to the original.


I think you didn't fix problem right.

You are still working on const string.

Fix:

You are actually making copy of string into "temp". But you are not
passing temp to "changeCustomerInfo()". You are still passing "c" to
"changeCustomerInfo()". "c" is const string, that is why the crash.

Instead you should pass "temp"

-Nagarajan Makala

Howard wrote:
"AMT2K5" <Aa*********@gmail.com> wrote in message
news:11********************@g49g2000cwa.googlegrou ps.com...
Hello guys.

I have a function, cleanSpace [which takes in a string such as
"this is\ta\ta a test". It cleans it up by removing new
lines/tabs and multiple/trailing and inbetween whitespace. I am
recieving a segmentation fault on one line when I apply it to a second
program [my second school assignment]. I was told from another source
that the problem is, is that the function is acting on constant string
literal. To fix this I was told to take the incoming string, copy it to
a buffer, work on the buffer and copy the buffer back to the original.
I tried but no sucess.

The seg fault is shown after the code snippet below.
int Account::cleanSpace(char c[])
{
int i=0,
j=0,
k=0,
m=0;

/* Ultimately this loop will scan for new lines and tabs and replace
them
with spaces. */
for(i=0; c[i]; i++)
{
if(c[i] == '\n' || c[i] == '\t')
c[i] = ' ';
}

/* For loop finds character starting point. */
for(i=0; c[i] == ' '; i++)
{
c[m] = c[i+1];
}

/* For loop moves all characters next to the first found character.
*/
for(i++; c[i]; i++)
{
c[++m] = c[i];
}

/* For loop removes trailing spaces. */
for(i = strlen(c) - 1; c[i] == ' '; i--)
{
c[i] = '\0';
}

/*For loop removes excess spaces. */
for(i = 0; c[i]; i++)
{
if(c[i] == ' ' && c[i+1] == ' ')
{
j = i;

while(c[j] == ' ')
{
j++;
}

for(k = i + 1; c[k]; k++, j++)
{
c[k] = c[j];
}
j=0;
}
}
return strlen(c);
}
Here is the function that calls it
int Account::changeCustomerInfo(char c[])
{
int result = 0;
char temp[251];
result = strlen(c) - 250;

cleanSpace(c); //Calls the cleanSpace function

if(strlen(c) <= 250){
strcpy(this->customer, c);
}
else{
for(int i = 0; i < 250; i++){
temp[i] = c[i];
}
strcpy(this->customer, temp);}

if(strlen(c) > 250){
return result;}

else return 0;
}
I recieve the seg fault on this code snippet below [which is found in
the cleanSpace function]

/* For loop moves all characters next to the first found character.
*/
for(i++; c[i]; i++)
{
c[++m] = c[i];
}

So by working with
int Account::cleanSpace(char c[]) function, how can I make it work not
on a string literal.

Thanks in advance. Appreciate any help whatsoever.


I didn't throughly analyze all conditions, but on the strings "XXX\t\n" and
" X ", it worked fine for me. (I substituted the member customer for a
local char[500] array, and made the functions global, but that shouldn't
affect things unless you've got other problems in the class that end up
causing this crash sometime later.) You should try debugging the app and
seeing what the values of c,i and m are the time it crashes. Perhaps
there's some condition you're not accounting for properly.

-Howard


Jul 23 '05 #5

P: n/a
ah forgot strcpy(temp, c);

Jul 23 '05 #6

P: n/a
AMT2K5 wrote:
Hello guys.

I have a function, cleanSpace [which takes in a string such as
"this is\ta\ta a test". It cleans it up by removing new
lines/tabs and multiple/trailing and inbetween whitespace. I am
recieving a segmentation fault on one line when I apply it to a second
program [my second school assignment]. I was told from another source
that the problem is, is that the function is acting on constant string
literal. To fix this I was told to take the incoming string, copy it to
a buffer, work on the buffer and copy the buffer back to the original.
I tried but no sucess.

[snip]
Thanks in advance. Appreciate any help whatsoever.


Here's some alternatives. Compile and run this program
to see how it works.

// cleanSpace.cpp
// trims leading and trailing whitespace from a string and
// replaces multiple sequential whitespace chars within
// the string with a single space.

// for cin and cout:
#include <iostream>

// for std::string:
#include <string>

// for std::istringstream and std::ostringstream
#include <sstream>

// for strcpy() and strdup()
#include <cstring>

// a version using a ref to a std::string as input.
// the input string ('str') is modified.
int cleanSpace(std::string& str)
{
if (0 == str.length())
return 0;

// no words read from the input yet
int wordCount = 0;

// make a string input stream from 'str'
std::istringstream wordsIn(str);

// make a string output stream to hold the result
std::ostringstream wordsOut;

// we'll read each word from the input string into 'word'
std::string word;

// while there is data in the input string stream
while (wordsIn)
{
// skip any leading whitespace and read the next word
// into 'word'
wordsIn >> word;

// if we actually read a word (i.e. we havn't reached
// the end of the input data
if (wordsIn)
{
// if we have already put at least one word
// to the output string, append a blank before
// we write the next word to the output string
if (wordCount)
wordsOut << ' ';

// append the word just read from the input string
// to the output string
wordsOut << word;

// erase the content of 'word' so it's ready to
// receive the next word read from the input string
word.erase();

// increment the count of words read from the input
// string
wordCount++;
}
}

// replace the original contents of 'str' with
// the content of the output string stream
str = wordsOut.str();

// return the final number of chars in 'str'
return str.length();
}
// a version using a char array as input.
// the input array ('c') is modified.
int cleanSpace(char * c)
{
if (NULL == c)
return 0;

int wordCount = 0;

// make an input string stream from the contents of 'c'.
std::istringstream wordsIn(c);

std::ostringstream wordsOut;
std::string word;

while (wordsIn)
{
wordsIn >> word;

if (wordsIn)
{
if (wordCount)
wordsOut << ' ';

wordsOut << word;
word.erase();
wordCount++;
}
}

// copy the contents of the output string stream
// to 'c' - replacing the original contents of 'c'
strcpy(c, wordsOut.str().c_str());

return strlen(c);
}

#if 0
// an alternate approach for using a char array.
// makes a string from the array, calls cleanSpace(string),
// then copies the result to the original input array ('c')
int cleanSpace(char * c)
{
if (NULL == c)
return 0;

int len;
std::string str(c);

len = cleanSpace(str);
strcpy(c, str.c_str());

return len;
}
#endif

int main()
{
int len;
char * c;
std::string s;

std::cout << "enter a string: ";
std::getline(std::cin, s);

// make a copy of the input string as a char array
c = strdup(s.c_str());

// call the version of cleanSpace() that takes a string
len = cleanSpace(s);
std::cout << "string len " << len << ": '" << s
<< "'" << std::endl;

// call the version of cleanSpace that takes a char array
len = cleanSpace(c);
std::cout << "c[] len " << len << ": '" << c
<< "'" << std::endl;

return 0;
}

Regards,
Larry
Jul 23 '05 #7

This discussion thread is closed

Replies have been disabled for this discussion.