Author Topic: Help with First Real C++ Program (Text Reverser) and Pointers  (Read 4794 times)

0 Members and 1 Guest are viewing this topic.

Offline Recon

  • Serf
  • *
  • Posts: 46
  • Cookies: 23
  • Arguing with Computer
    • View Profile
Help with First Real C++ Program (Text Reverser) and Pointers
« on: December 29, 2013, 11:46:45 pm »
Dear Evilzone community,

Looking to learn how to program, I decided to dive in headfirst, as I have seen recommended, and actually program something. To that end, I decided on a simple command-line program which would be capable of reversing an entire text file, reversing each line of the file independently (without changing their overall order), or reversing each word of the file independently (without changing the order of the words). Unfortunately, I have encountered difficulties with pointers as they pertain to passing strings (char arrays) which have stalled my progress. I've included my code below, and would much appreciate it if someone could help me correct my usage of pointers and/or variable scopes, or tell me whether I'm going about this in entirely the wrong manner.

Code: [Select]
#include <fstream>
#include <iostream>

using namespace std;

char* reverseString(char input[]);

int main(){
    char *myStr = "Hiya!";
    char *output = reverseString[*myStr];
    cout << output;
}

char *reverseString(char *input) { // reverses the order of a string
    int bufferSize = strlen(input);
    char *output = new char[bufferSize];
    for(int i = 0; i < bufferSize; i++) {
        output[(bufferSize - 1) - i] = input[i];
    }
    return output;
}

Offline bluechill

  • Cybermancer
  • Royal Highness
  • ****
  • Posts: 682
  • Cookies: 344
  • I am the existence in these walls
    • View Profile
Re: Help with First Real C++ Program (Text Reverser) and Pointers
« Reply #1 on: December 30, 2013, 02:44:52 am »
You have to allocate memory.  When you do:

char* temp = "Blah";

You are assigning the address temp points to to "Blah" in ASCII.

Try:

char* temp = new char[5];
*temp = "Ten!!";

cout << *temp;
I have dreamed a dream, but now that dream has gone from me.  In its place now exists my own reality, a reality which I have created for myself by myself.

Offline Recon

  • Serf
  • *
  • Posts: 46
  • Cookies: 23
  • Arguing with Computer
    • View Profile
Re: Help with First Real C++ Program (Text Reverser) and Pointers
« Reply #2 on: December 30, 2013, 03:34:26 am »
You have to allocate memory.  When you do:

char* temp = "Blah";

You are assigning the address temp points to to "Blah" in ASCII.

Try:

char* temp = new char[5];
*temp = "Ten!!";

cout << *temp;

I tried that, as you can see in the following code (which I modified slightly from how you put it, because the compiler squawked at me about the leading asterisk), but it didn't fix my problem. That particular portion of the code wasn't triggering an error before either (but maybe it would have at run time). The error is coming up at line 11 of the following code.
Code: [Select]
#include <fstream>
#include <iostream>

using namespace std;

char* reverseString(char input[]);

int main(){
    char *myStr = new char[5];
    myStr = "Hiya!";
    char *output = reverseString[*myStr];
    cout << output;
}

char *reverseString(char *input) { // reverses the order of a string
    int bufferSize = strlen(input);
    char *output = new char[bufferSize];
    for(int i = 0; i < bufferSize; i++) {
        output[(bufferSize - 1) - i] = input[i];
    }
    return output;
}

Offline bluechill

  • Cybermancer
  • Royal Highness
  • ****
  • Posts: 682
  • Cookies: 344
  • I am the existence in these walls
    • View Profile
Re: Help with First Real C++ Program (Text Reverser) and Pointers
« Reply #3 on: December 30, 2013, 04:13:29 am »
I tried that, as you can see in the following code (which I modified slightly from how you put it, because the compiler squawked at me about the leading asterisk), but it didn't fix my problem. That particular portion of the code wasn't triggering an error before either (but maybe it would have at run time). The error is coming up at line 11 of the following code.
Code: [Select]
#include <fstream>
#include <iostream>

using namespace std;

char* reverseString(char input[]);

int main(){
    char *myStr = new char[5];
    myStr = "Hiya!";
    char *output = reverseString[*myStr];
    cout << output;
}

char *reverseString(char *input) { // reverses the order of a string
    int bufferSize = strlen(input);
    char *output = new char[bufferSize];
    for(int i = 0; i < bufferSize; i++) {
        output[(bufferSize - 1) - i] = input[i];
    }
    return output;
}

get a better compiler if it did.  It should be

*myStr = "Hiya!"
I have dreamed a dream, but now that dream has gone from me.  In its place now exists my own reality, a reality which I have created for myself by myself.

Offline bluechill

  • Cybermancer
  • Royal Highness
  • ****
  • Posts: 682
  • Cookies: 344
  • I am the existence in these walls
    • View Profile
Re: Help with First Real C++ Program (Text Reverser) and Pointers
« Reply #4 on: December 30, 2013, 04:16:16 am »
Or since you're using C++ use strings.  But if you still want to use C strings use strncpy
I have dreamed a dream, but now that dream has gone from me.  In its place now exists my own reality, a reality which I have created for myself by myself.

Offline Recon

  • Serf
  • *
  • Posts: 46
  • Cookies: 23
  • Arguing with Computer
    • View Profile
Re: Help with First Real C++ Program (Text Reverser) and Pointers
« Reply #5 on: December 30, 2013, 04:21:14 am »
get a better compiler if it did.  It should be

*myStr = "Hiya!"

Is Visual Studio 2012 Express not the right thing to be using? I'm not sure what else to use on Windows, and I haven't yet made the move to Linux.

Offline bluechill

  • Cybermancer
  • Royal Highness
  • ****
  • Posts: 682
  • Cookies: 344
  • I am the existence in these walls
    • View Profile
Re: Help with First Real C++ Program (Text Reverser) and Pointers
« Reply #6 on: December 30, 2013, 04:27:03 am »
Is Visual Studio 2012 Express not the right thing to be using? I'm not sure what else to use on Windows, and I haven't yet made the move to Linux.

VS 2012 doesn't truly have full standards support unfortunately.  It's missing all of C99 I believe and a chunk of the prior standard to that so it doesn't support those fun stuff.  It does support strn* stuff though
I have dreamed a dream, but now that dream has gone from me.  In its place now exists my own reality, a reality which I have created for myself by myself.

Offline Kulverstukas

  • Administrator
  • Zeus
  • *
  • Posts: 6627
  • Cookies: 542
  • Fascist dictator
    • View Profile
    • My blog
Re: Help with First Real C++ Program (Text Reverser) and Pointers
« Reply #7 on: December 30, 2013, 07:10:00 am »
I recommend CodeBlocks and GNU C++ (gcc). Great for little programs like this and bigger projects. But later you'll demand a better debugger and better code completion heh :P

Offline Recon

  • Serf
  • *
  • Posts: 46
  • Cookies: 23
  • Arguing with Computer
    • View Profile
Re: Help with First Real C++ Program (Text Reverser) and Pointers
« Reply #8 on: January 05, 2014, 03:32:45 am »
So, I went back and re-wrote this to try to use strings. The problem is, I've tried five different approaches that I thought would be logical ways of appending a character to a string, and none of them work. They all cause run-time exceptions. Can someone set me straight as to how I might go about doing this? I've marked the error in the code below.

Code: [Select]
#include <string>
#include <iostream>

using namespace std;

string reverseString(string input);

int main(){
    string myString = "Hiya!";
    string myOtherString = reverseString(myString);
    cout << myOtherString;
}

string reverseString(string input) {
    string output;
    for (int i = input.length - 1; i >= 0; i--) {
        output.push_back(input.at(i));   //error on this line, various combinations of input[i], +=, append, and the functions shown all fail
    }
}

Offline bluechill

  • Cybermancer
  • Royal Highness
  • ****
  • Posts: 682
  • Cookies: 344
  • I am the existence in these walls
    • View Profile
Re: Help with First Real C++ Program (Text Reverser) and Pointers
« Reply #9 on: January 05, 2014, 05:17:51 am »
So, I went back and re-wrote this to try to use strings. The problem is, I've tried five different approaches that I thought would be logical ways of appending a character to a string, and none of them work. They all cause run-time exceptions. Can someone set me straight as to how I might go about doing this? I've marked the error in the code below.

Code: [Select]
#include <string>
#include <iostream>

using namespace std;

string reverseString(string input);

int main(){
    string myString = "Hiya!";
    string myOtherString = reverseString(myString);
    cout << myOtherString;
}

string reverseString(string input) {
    string output;
    for (int i = input.length - 1; i >= 0; i--) {
        output.push_back(input.at(i));   //error on this line, various combinations of input[i], +=, append, and the functions shown all fail
    }
}


Your error isn't where the compiler says it is.  The error is actually on the line above it.  length is a function not a public member, so call input.length() not input.length.  This isn't C# or the fuck w/e uses it as a public member.
I have dreamed a dream, but now that dream has gone from me.  In its place now exists my own reality, a reality which I have created for myself by myself.

Offline Recon

  • Serf
  • *
  • Posts: 46
  • Cookies: 23
  • Arguing with Computer
    • View Profile
Re: Help with First Real C++ Program (Text Reverser) and Pointers
« Reply #10 on: January 05, 2014, 09:24:03 pm »
Thanks, bluechill! I got a basic version of my program working.

I have another question, though. How do I pause the program after accepting a getline() input? I've tried cin.get(), cin.ignore(), and getchar(), but none of them seems to work. The program just blitzes through when I hit enter. I've even tried stacking them, which seemed to fix my problems with the plain cin input I used for the menu, but isn't helping with the getline input (and besides, it makes using option two a pain because you have to hit enter twice to close the program). The command system("pause") doesn't seem to work either; it just hangs the program indefinitely, although that could be the fault of my firewall. What would you recommend?

Also, is there a less butt-ugly way of dealing with option 2 than stacking two cin.ignore() commands, or is that just a reality of life?

EDIT: I messed around a little and found some interesting behavior. I've included a second block of code below for which option 2 will automatically close after the sleep function. Any idea what is causing this?

EDIT 2: I've modified the code to include six cin.ignore() functions; this seems to fix the auto-closing issue, but now it's not outputting the text at all before it closes.

Code: [Select]
// when choosing menu option 1, program exits execution without pausing to display output
#include <string>
#include <iostream>
#include <sstream>

using namespace std;

string reverseString(string input);
string reverseManualInput();

int main(){
    string myOutput;
    short menuOption;
    cout << "1. Reverse Manual Line Input\n";
    cout << "2. Reverse Preset Test String\n";
    cin >> menuOption;
    switch (menuOption)
    {
    case 1:
        myOutput = reverseManualInput();
        break;
    case 2:
        myOutput = reverseString("Hello World!");
        break;
    default:
        break;
    }
    cout << myOutput;
    cin.ignore();
    cin.ignore();
}

string reverseManualInput() {
    string input;
    string output;
    getline(cin, input);
    output = reverseString(input);
    return output;
}

string reverseString(string input) {
    string output;
    for (int i = input.length() - 1; i >= 0; i--) {
        output.push_back(input.at(i));
    }
    return output;
}

Code: [Select]
#include <string>
#include <iostream>
#include <sstream>
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
#include <dos.h>
#include <Windows.h>

using namespace std;

string reverseString(string input);
string reverseManualInput();

int main(){
    string myOutput;
    short menuOption;
    cout << "1. Reverse Manual Line Input\n";
    cout << "2. Reverse Preset Test String\n";
    cin >> menuOption;
    switch (menuOption)
    {
    case 1:
        myOutput = reverseManualInput();
        break;
    case 2:
        myOutput = reverseString("Hello World!");
        break;
    default:
        break;
    }
    cout << myOutput;
    Sleep(4000); //seems to do this before accepting manual string output
    cin.ignore();
}

string reverseManualInput() {
    string input;
    string output;
    getline(cin, input);
    output = reverseString(input);
    return output;
}

string reverseString(string input) {
    string output;
    for (int i = input.length() - 1; i >= 0; i--) {
        output.push_back(input.at(i));
    }
    return output;
}
« Last Edit: January 05, 2014, 09:42:41 pm by Recon »

Offline bluechill

  • Cybermancer
  • Royal Highness
  • ****
  • Posts: 682
  • Cookies: 344
  • I am the existence in these walls
    • View Profile
Re: Help with First Real C++ Program (Text Reverser) and Pointers
« Reply #11 on: January 06, 2014, 03:00:14 am »
Thanks, bluechill! I got a basic version of my program working.

I have another question, though. How do I pause the program after accepting a getline() input? I've tried cin.get(), cin.ignore(), and getchar(), but none of them seems to work. The program just blitzes through when I hit enter. I've even tried stacking them, which seemed to fix my problems with the plain cin input I used for the menu, but isn't helping with the getline input (and besides, it makes using option two a pain because you have to hit enter twice to close the program). The command system("pause") doesn't seem to work either; it just hangs the program indefinitely, although that could be the fault of my firewall. What would you recommend?

Also, is there a less butt-ugly way of dealing with option 2 than stacking two cin.ignore() commands, or is that just a reality of life?

EDIT: I messed around a little and found some interesting behavior. I've included a second block of code below for which option 2 will automatically close after the sleep function. Any idea what is causing this?

EDIT 2: I've modified the code to include six cin.ignore() functions; this seems to fix the auto-closing issue, but now it's not outputting the text at all before it closes.

Code: [Select]
// when choosing menu option 1, program exits execution without pausing to display output
#include <string>
#include <iostream>
#include <sstream>

using namespace std;

string reverseString(string input);
string reverseManualInput();

int main(){
    string myOutput;
    short menuOption;
    cout << "1. Reverse Manual Line Input\n";
    cout << "2. Reverse Preset Test String\n";
    cin >> menuOption;
    switch (menuOption)
    {
    case 1:
        myOutput = reverseManualInput();
        break;
    case 2:
        myOutput = reverseString("Hello World!");
        break;
    default:
        break;
    }
    cout << myOutput;
    cin.ignore();
    cin.ignore();
}

string reverseManualInput() {
    string input;
    string output;
    getline(cin, input);
    output = reverseString(input);
    return output;
}

string reverseString(string input) {
    string output;
    for (int i = input.length() - 1; i >= 0; i--) {
        output.push_back(input.at(i));
    }
    return output;
}

Code: [Select]
#include <string>
#include <iostream>
#include <sstream>
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
#include <dos.h>
#include <Windows.h>

using namespace std;

string reverseString(string input);
string reverseManualInput();

int main(){
    string myOutput;
    short menuOption;
    cout << "1. Reverse Manual Line Input\n";
    cout << "2. Reverse Preset Test String\n";
    cin >> menuOption;
    switch (menuOption)
    {
    case 1:
        myOutput = reverseManualInput();
        break;
    case 2:
        myOutput = reverseString("Hello World!");
        break;
    default:
        break;
    }
    cout << myOutput;
    Sleep(4000); //seems to do this before accepting manual string output
    cin.ignore();
}

string reverseManualInput() {
    string input;
    string output;
    getline(cin, input);
    output = reverseString(input);
    return output;
}

string reverseString(string input) {
    string output;
    for (int i = input.length() - 1; i >= 0; i--) {
        output.push_back(input.at(i));
    }
    return output;
}

There is no "pausing" other than running a while loop or sleep() and the reason it's not outputting any text is because you need to flush the output buffer.
I have dreamed a dream, but now that dream has gone from me.  In its place now exists my own reality, a reality which I have created for myself by myself.

Offline Recon

  • Serf
  • *
  • Posts: 46
  • Cookies: 23
  • Arguing with Computer
    • View Profile
Re: Help with First Real C++ Program (Text Reverser) and Pointers
« Reply #12 on: January 06, 2014, 09:05:12 pm »
EDIT: Never mind. I got it.
« Last Edit: January 11, 2014, 12:28:34 am by Recon »

Offline ArkPhaze

  • Peasant
  • *
  • Posts: 136
  • Cookies: 20
  • null terminated
    • View Profile
Re: Help with First Real C++ Program (Text Reverser) and Pointers
« Reply #13 on: January 26, 2014, 06:58:37 am »
As above, if you're using C++, why not use the string alias? Otherwise, in C, you can do this with recursion pretty easy too. Here's a method I wrote a while back:

Code: [Select]
#include <stdio.h>
#include <string.h>

void reverse_str_recur(char *s, int lower_index, int upper_index)
{
   if (upper_index <= lower_index) return;
   char c[2] = {s[lower_index], s[upper_index]};
   memcpy(s + lower_index, c + 1, 1);
   memcpy(s + upper_index, c, 1);
   reverse_str_recur(s, upper_index - 1, lower_index + 1);
}
void reverse_str(char *s)
{
   reverse_str_recur(s, 0, strlen(s) - 1);
}

int main()
{
   char str[] = "12345";
   printf("Original: %s\n", str);
   reverse_str(str);
   printf("Reversed: %s\n", str);
   return 0;
}

Just remember with C style strings you have a null terminator to work with.
« Last Edit: January 26, 2014, 07:01:28 am by ArkPhaze »
sig=: ArkPhaze

[ J/ASM/.NET/C/C++ - Software Engineer ]

Offline Stackprotector

  • Administrator
  • Titan
  • *
  • Posts: 2515
  • Cookies: 205
    • View Profile
Re: Help with First Real C++ Program (Text Reverser) and Pointers
« Reply #14 on: January 26, 2014, 04:34:47 pm »
As above, if you're using C++, why not use the string alias? Otherwise, in C, you can do this with recursion pretty easy too. Here's a method I wrote a while back:

Code: [Select]
#include <stdio.h>
#include <string.h>

void reverse_str_recur(char *s, int lower_index, int upper_index)
{
   if (upper_index <= lower_index) return;
   char c[2] = {s[lower_index], s[upper_index]};
   memcpy(s + lower_index, c + 1, 1);
   memcpy(s + upper_index, c, 1);
   reverse_str_recur(s, upper_index - 1, lower_index + 1);
}
void reverse_str(char *s)
{
   reverse_str_recur(s, 0, strlen(s) - 1);
}

int main()
{
   char str[] = "12345";
   printf("Original: %s\n", str);
   reverse_str(str);
   printf("Reversed: %s\n", str);
   return 0;
}

Just remember with C style strings you have a null terminator to work with.
Why call memcall every time while you can just use basic assignment s[index] = char
~Factionwars